Comment extraire le substrat entre deux marqueurs?
disons que j'ai une chaîne 'gfgfdAAA1234ZZZuijjk'
et je veux extraire juste la partie '1234'
.
Je ne sais que les quelques caractères qui précéderont AAA
, et après ZZZ
la partie qui m'intéresse 1234
.
avec sed
il est possible de faire quelque chose comme cela avec une chaîne:
echo "$STRING" | sed -e "s|.*AAA(.*)ZZZ.*||"
et cela me donnera 1234
comme résultat.
How faire la même chose en Python?
12 réponses
utilisant des expressions régulières - documentation pour référence ultérieure
import re
text = 'gfgfdAAA1234ZZZuijjk'
m = re.search('AAA(.+?)ZZZ', text)
if m:
found = m.group(1)
# found: 1234
ou:
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 = 'gfgfdAAA1234ZZZuijjk'
>>> start = s.find('AAA') + 3
>>> end = s.find('ZZZ', start)
>>> s[start:end]
'1234'
alors vous pouvez utiliser regexps avec le module re aussi, si vous voulez, mais ce n'est pas nécessaire dans votre cas.
expression régulière
import re
re.search(r"(?<=AAA).*?(?=ZZZ)", your_text).group(0)
ceux d'en haut-est échouera avec un AttributeError
si il n'y a pas de "AAA" et "ZZZ" dans your_text
méthodes string
your_text.partition("AAA")[2].partition("ZZZ")[0]
la chaîne ci-dessus retournera une chaîne vide si" AAA "ou" ZZZ "n'existent pas dans your_text
.
PS Python Challenge?
import re
print re.search('AAA(.*?)ZZZ', 'gfgfdAAA1234ZZZuijjk').group(1)
vous pouvez utiliser re module pour cela:
>>> import re
>>> re.compile(".*AAA(.*)ZZZ.*").match("gfgfdAAA1234ZZZuijjk").groups()
('1234,)
avec sed il est possible de faire quelque chose comme ceci avec une chaîne:
echo "$STRING" | sed -e "s|.*AAA\(.*\)ZZZ.*||"
et cela me donnera 1234 comme résultat.
vous pouvez faire la même chose avec re.sub
fonction en utilisant le même regex.
>>> re.sub(r'.*AAA(.*)ZZZ.*', r'', 'gfgfdAAA1234ZZZuijjk')
'1234'
dans basic sed, le groupe de capture est représenté par \(..\)
, mais en python il est représenté par (..)
.
vous pouvez trouver la première chaîne avec cette fonction dans votre code (par index de caractères). Aussi, vous pouvez trouver ce qui est après un substrat.
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]))
juste au cas où quelqu'un devrait faire la même chose que moi. J'ai dû extraire tout ce qui était entre parenthèses dans une ligne. Par exemple, si j'ai une ligne comme " le président des États-Unis (Barack Obama) rencontré ..."et je veux obtenir seulement" Barack Obama " c'est la solution:
regex = '.*\((.*?)\).*'
matches = re.search(regex, line)
line = matches.group(1) + '\n'
i. e. vous devez bloquer la parenthèse avec le signe slash \
. Bien que ce soit un problème sur les expressions plus régulières que Python.
Aussi, dans certains cas, vous pouvez voir symboles " r " avant la définition de regex. S'il n'y a pas de préfixe r, Vous devez utiliser des caractères d'échappement comme dans C. ici est plus de discussion sur ce.
vous pouvez le faire en utilisant une seule ligne de code
>>> import re
>>> re.findall(r'\d{1,5}','gfgfdAAA1234ZZZuijjk')
>>> ['1234']
résultat recevra la liste...
>>> s = '/tmp/10508.constantstring'
>>> s.split('/tmp/')[1].split('constantstring')[0].strip('.')
en python, l'extraction de chaîne de formes de substrats peut être effectuée en utilisant la méthode findall
dans le module d'expression régulière ( re
).
>>> import re
>>> s = 'gfgfdAAA1234ZZZuijjk'
>>> ss = re.findall('AAA(.+)ZZZ', s)
>>> print ss
['1234']
une doublure qui renvoie une autre chaîne s'il n'y a pas de correspondance.
Modifier: la version améliorée utilise la fonction next
, remplacer "not-found"
par quelque chose d'autre si nécessaire:
import re
res = next( (m.group(1) for m in [re.search("AAA(.*?)ZZZ", "gfgfdAAA1234ZZZuijjk" ),] if m), "not-found" )
mon autre méthode pour faire ceci, moins optimal, utilise regex 2ème fois, n'a toujours pas trouvé un chemin plus court:
import re
res = ( ( re.search("AAA(.*?)ZZZ", "gfgfdAAA1234ZZZuijjk") or re.search("()","") ).group(1) )