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?

191
demandé sur Aran-Fey 2011-01-12 12:14:21

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
364
répondu eumiro 2013-10-08 15:50:59
>>> 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.

82
répondu Lennart Regebro 2011-01-12 09:17:23

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?

31
répondu tzot 2011-02-06 23:43:17
import re
print re.search('AAA(.*?)ZZZ', 'gfgfdAAA1234ZZZuijjk').group(1)
13
répondu infrared 2011-01-12 09:18:00

vous pouvez utiliser re module pour cela:

>>> import re
>>> re.compile(".*AAA(.*)ZZZ.*").match("gfgfdAAA1234ZZZuijjk").groups()
('1234,)
6
répondu andreypopp 2011-01-12 09:19:21

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 (..) .

5
répondu Avinash Raj 2015-01-31 08:29:21

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]))
4
répondu Saeed Zahedian Abroodi 2017-10-21 05:38:35

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.

2
répondu wzbozon 2017-05-23 11:55:07

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...

2
répondu mahesh gupta 2018-01-11 11:39:55
>>> s = '/tmp/10508.constantstring'
>>> s.split('/tmp/')[1].split('constantstring')[0].strip('.')
1
répondu user1810100 2014-02-11 09:23:44

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']
0
répondu rashok 2018-03-14 09:11:23

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) )
0
répondu MaxLZ 2018-05-03 18:31:44