web-dev-qa-db-fra.com

Comment extraire la sous-chaîne entre deux marqueurs?

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?

226
miernik

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

87
Lennart Regebro

expression régulière

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

méthodes de chaîne

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?

39
tzot
import re
print re.search('AAA(.*?)ZZZ', 'gfgfdAAA1234ZZZuijjk').group(1)
13
infrared

Vous pouvez utiliser re module pour cela:

>>> import re
>>> re.compile(".*AAA(.*)ZZZ.*").match("gfgfdAAA1234ZZZuijjk").groups()
('1234,)
7
andreypopp

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]))
4

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

3
mahesh gupta

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. 

2
wzbozon

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']
2
rashok

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'
1
Uncle Long Hair
>>> s = '/tmp/10508.constantstring'
>>> s.split('/tmp/')[1].split('constantstring')[0].strip('.')
1
user1810100
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
0

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)]
0
Roymunson