Cómo extraer la subcadena entre dos marcadores?
Digamos que tengo una cadena 'gfgfdAAA1234ZZZuijjk'
y quiero extraer solo la parte '1234'
.
Solo sé cuáles serán los pocos caracteres directamente antes AAA
, y después ZZZ
de la parte que me interesa 1234
.
Con sed
es posible hacer algo como esto con una cadena:
echo "$STRING" | sed -e "s|.*AAA\(.*\)ZZZ.*|\1|"
Y esto me dará 1234
como resultado.
Cómo hacer lo mismo en Python?
12 answers
Usando expresiones regulares - documentación para mayor referencia
import re
text = 'gfgfdAAA1234ZZZuijjk'
m = re.search('AAA(.+?)ZZZ', text)
if m:
found = m.group(1)
# found: 1234
O:
import re
text = 'gfgfdAAA1234ZZZuijjk'
try:
found = re.search('AAA(.+?)ZZZ', text).group(1)
except AttributeError:
# AAA, ZZZ not found in the original string
found = '' # apply your error handling
# found: 1234
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-08 15:50:59
>>> s = 'gfgfdAAA1234ZZZuijjk'
>>> start = s.find('AAA') + 3
>>> end = s.find('ZZZ', start)
>>> s[start:end]
'1234'
Entonces también puede usar expresiones regulares con el módulo re, si lo desea, pero eso no es necesario en su caso.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-12 09:17:23
Expresión regular
import re
re.search(r"(?<=AAA).*?(?=ZZZ)", your_text).group(0)
El as-is anterior fallará con un AttributeError
si no hay " AAA "y" ZZZ " en your_text
Métodos de cadena
your_text.partition("AAA")[2].partition("ZZZ")[0]
Lo anterior devolverá una cadena vacía si "AAA" o "ZZZ" no existen en your_text
.
PS Python Challenge?
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-06 23:43:17
import re
print re.search('AAA(.*?)ZZZ', 'gfgfdAAA1234ZZZuijjk').group(1)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-12 09:18:00
Puedes usar el módulo re para eso:
>>> import re
>>> re.compile(".*AAA(.*)ZZZ.*").match("gfgfdAAA1234ZZZuijjk").groups()
('1234,)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-12 09:19:21
Con sed es posible hacer algo como esto con una cadena:
echo "$STRING" | sed -e "s|.*AAA\(.*\)ZZZ.*|\1|"
Y esto me dará 1234 como resultado.
Podrías hacer lo mismo con la función re.sub
usando la misma expresión regular.
>>> re.sub(r'.*AAA(.*)ZZZ.*', r'\1', 'gfgfdAAA1234ZZZuijjk')
'1234'
En sed básico, el grupo de captura está representado por \(..\)
, pero en python estaba representado por (..)
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-31 08:29:21
Puede encontrar la primera subcadena con esta función en su código (por índice de caracteres). Además, puede encontrar lo que está después de una subcadena.
def FindSubString(strText, strSubString, Offset=None):
try:
Start = strText.find(strSubString)
if Start == -1:
return -1 # Not Found
else:
if Offset == None:
Result = strText[Start+len(strSubString):]
elif Offset == 0:
return Start
else:
AfterSubString = Start+len(strSubString)
Result = strText[AfterSubString:AfterSubString + int(Offset)]
return Result
except:
return -1
# Example:
Text = "Thanks for contributing an answer to Stack Overflow!"
subText = "to"
print("Start of first substring in a text:")
start = FindSubString(Text, subText, 0)
print(start); print("")
print("Exact substring in a text:")
print(Text[start:start+len(subText)]); print("")
print("What is after substring \"%s\"?" %(subText))
print(FindSubString(Text, subText))
# Your answer:
Text = "gfgfdAAA1234ZZZuijjk"
subText1 = "AAA"
subText2 = "ZZZ"
AfterText1 = FindSubString(Text, subText1, 0) + len(subText1)
BeforText2 = FindSubString(Text, subText2, 0)
print("\nYour answer:\n%s" %(Text[AfterText1:BeforText2]))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-21 05:38:35
Por si acaso alguien tendrá que hacer lo mismo que yo. Tuve que extraer todo dentro de paréntesis en una línea. Por ejemplo, si tengo una línea como 'presidente de estados unidos (Barack Obama) se reunió con ...'y quiero obtener solo' Barack Obama ' esta es la solución:
regex = '.*\((.*?)\).*'
matches = re.search(regex, line)
line = matches.group(1) + '\n'
Es decir, debe bloquear el paréntesis con el signo slash \
. Aunque es un problema sobre expresiones más regulares que Python.
También, en algunos casos puede ver símbolos 'r' antes de la definición de expresiones regulares. Si no hay r prefijo, necesita usar caracteres de escape como en C. Aquí hay más discusión sobre eso.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:55:07
Puede hacerlo usando solo una línea de código
>>> import re
>>> re.findall(r'\d{1,5}','gfgfdAAA1234ZZZuijjk')
>>> ['1234']
El resultado recibirá la lista...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-11 11:39:55
>>> s = '/tmp/10508.constantstring'
>>> s.split('/tmp/')[1].split('constantstring')[0].strip('.')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-11 09:23:44
En python, la extracción de una cadena de forma de subcadena se puede hacer usando el método findall
en el módulo de expresión regular (re
).
>>> import re
>>> s = 'gfgfdAAA1234ZZZuijjk'
>>> ss = re.findall('AAA(.+)ZZZ', s)
>>> print ss
['1234']
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-14 09:11:23
Una línea que devuelve otra cadena si no hay coincidencia.
Editar: la versión mejorada usa la función next
, reemplaza "not-found"
con algo más si es necesario:
import re
res = next( (m.group(1) for m in [re.search("AAA(.*?)ZZZ", "gfgfdAAA1234ZZZuijjk" ),] if m), "not-found" )
Mi otro método para hacer esto, menos óptimo, utiliza regex 2nd tiempo, todavía no encontró una manera más corta:
import re
res = ( ( re.search("AAA(.*?)ZZZ", "gfgfdAAA1234ZZZuijjk") or re.search("()","") ).group(1) )
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-03 18:31:44