Disons que j'ai une chaîne 'gfgfdAAA1234ZZZuijjk'
et que je veux extraire uniquement la partie '1234'
.
Je sais seulement quels seront les quelques caractères directement avant AAA
et après ZZZ
la partie qui m'intéresse 1234
.
Avec sed
, il est possible de faire quelque chose comme ceci avec une chaîne:
echo "$STRING" | sed -e "s|.*AAA\(.*\)ZZZ.*|\1|"
Et cela me donnera 1234
à la suite.
Comment faire la même chose en Python?
Utilisation d'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'
Vous pouvez ensuite utiliser les expressions rationnelles avec le module re également, si vous le souhaitez, mais ce n'est pas nécessaire dans votre cas.
import re
re.search(r"(?<=AAA).*?(?=ZZZ)", your_text).group(0)
La procédure ci-dessus échouera avec une AttributeError
s'il n'y a ni "AAA" ni "ZZZ" dans your_text
your_text.partition("AAA")[2].partition("ZZZ")[0]
Ce qui précède renvoie une chaîne vide si "AAA" ou "ZZZ" n'existe pas dans your_text
.
Défi PS Python?
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,)
Vous pouvez trouver la première sous-chaîne avec cette fonction dans votre code (par index de caractères). En outre, vous pouvez trouver ce qui se trouve après une sous-chaîne.
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]))
vous pouvez faire en utilisant une seule ligne de code
>>> import re
>>> re.findall(r'\d{1,5}','gfgfdAAA1234ZZZuijjk')
>>> ['1234']
le résultat recevra la liste ...
Juste au cas où quelqu'un devra faire la même chose que moi. Je devais extraire tout ce qui se trouvait entre parenthèses en ligne. Par exemple, si j'ai une phrase comme "Le président américain (Barack Obama) a rencontré ..." et que je souhaite obtenir uniquement "Barack Obama", voici la solution:
regex = '.*\((.*?)\).*'
matches = re.search(regex, line)
line = matches.group(1) + '\n'
C'est à dire. vous devez bloquer les parenthèses avec le signe slash \
. Bien que ce soit un problème au sujet des expressions plus régulières que Python.
En outre, dans certains cas, vous pouvez voir les symboles "r" avant la définition de l'expression rationnelle. S'il n'y a pas de préfixe r, vous devez utiliser des caractères d'échappement comme en C. Ici il y a davantage de discussion à ce sujet.
En python, l'extraction de sous-chaîne d'une chaîne peut être effectuée à l'aide de la méthode findall
du module expression régulière (re
).
>>> import re
>>> s = 'gfgfdAAA1234ZZZuijjk'
>>> ss = re.findall('AAA(.+)ZZZ', s)
>>> print ss
['1234']
Surpris que personne ne l'ait mentionné, ce qui est ma version rapide pour les scripts uniques:
>>> x = 'gfgfdAAA1234ZZZuijjk'
>>> x.split('AAA')[1].split('ZZZ')[0]
'1234'
>>> s = '/tmp/10508.constantstring'
>>> s.split('/tmp/')[1].split('constantstring')[0].strip('.')
text = 'I want to find a string between two substrings'
left = 'find a '
right = 'between two'
print(text[text.index(left)+len(left):text.index(right)])
Donne
string
Voici une solution sans regex qui tient également compte des scénarios dans lesquels la première sous-chaîne contient la deuxième sous-chaîne. Cette fonction ne trouvera une sous-chaîne que si le deuxième marqueur est après le premier marqueur.
def find_substring(string, start, end):
len_until_end_of_first_match = string.find(start) + len(start)
after_start = string[len_until_end_of_first_match:]
return string[string.find(start) + len(start):len_until_end_of_first_match + after_start.find(end)]