python - length - ¿Cómo extraer la subcadena entre dos marcadores?
substring python ejemplo (12)
Con sed es posible hacer algo como esto con una cuerda:
echo "$STRING" | sed -e "s|.*AAA/(.*/)ZZZ.*|/1|"
Y esto me dará 1234 como resultado.
Podría 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 estuvo representado por (..)
.
Digamos que tengo una cadena ''gfgfdAAA1234ZZZuijjk''
y quiero extraer solo la parte ''1234''
.
Solo sé cuáles serán los pocos caracteres directamente antes de AAA
, y después de ZZZ
la parte que me interesa es 1234
.
Con sed
es posible hacer algo como esto con una cuerda:
echo "$STRING" | sed -e "s|.*AAA/(.*/)ZZZ.*|/1|"
Y esto me dará 1234
como resultado.
¿Cómo hacer lo mismo en Python?
Puede encontrar la primera subcadena con esta función en su código (por índice de caracteres). Además, puedes 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 !"
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]))
expresión regular
import re
re.search(r"(?<=AAA).*?(?=ZZZ)", your_text).group(0)
Tal como está, fallará con un AttributeError
si no hay "AAA" y "ZZZ" en su 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?
En Python, la cadena de formulario de extracción de subcadenas se puede hacer usando el método findall
en el módulo ( re
) de expresiones regulares.
>>> import re
>>> s = ''gfgfdAAA1234ZZZuijjk''
>>> ss = re.findall(''AAA(.+)ZZZ'', s)
>>> print ss
[''1234'']
Puedes hacerlo usando solo una línea de código
>>> import re
>>> re.findall(r''/d{1,5}'',''gfgfdAAA1234ZZZuijjk'')
>>> [''1234'']
el resultado recibirá la lista ...
Puedes usar re modulo para eso:
>>> import re
>>> re.compile(".*AAA(.*)ZZZ.*").match("gfgfdAAA1234ZZZuijjk").groups()
(''1234,)
Solo en caso de que alguien tenga que hacer lo mismo que yo hice. Tuve que extraer todo dentro de paréntesis en una línea. Por ejemplo, si tengo una línea como "El presidente de EE. UU. (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, necesitas bloquear paréntesis con slash /
signo. Aunque es un problema sobre expresiones más regulares que Python.
Además, en algunos casos puede ver los símbolos ''r'' antes de la definición de expresiones regulares. Si no hay un prefijo r, necesita usar caracteres de escape como en C. Here hay más discusión sobre eso.
Un forro que devuelve otra cadena si no hubo coincidencia. Edición: la versión mejorada usa la next
función, reemplaza "not-found"
con otra cosa 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, usa expresiones regulares por segunda vez, todavía no encontré una forma más corta:
import re
res = ( ( re.search("AAA(.*?)ZZZ", "gfgfdAAA1234ZZZuijjk") or re.search("()","") ).group(1) )
Uso de expresiones regulares - documentation para futuras referencias
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
>>> s = ''/tmp/10508.constantstring''
>>> s.split(''/tmp/'')[1].split(''constantstring'')[0].strip(''.'')
>>> s = ''gfgfdAAA1234ZZZuijjk''
>>> start = s.find(''AAA'') + 3
>>> end = s.find(''ZZZ'', start)
>>> s[start:end]
''1234''
Luego puede usar expresiones regulares con el módulo re también, si lo desea, pero eso no es necesario en su caso.
import re
print re.search(''AAA(.*?)ZZZ'', ''gfgfdAAA1234ZZZuijjk'').group(1)