it-swarm.com.de

Wie extrahiere ich den Teilstring zwischen zwei Markern?

Nehmen wir an, ich habe einen String 'gfgfdAAA1234ZZZuijjk' und ich möchte nur den '1234'-Teil extrahieren.

Ich weiß nur, was die wenigen Zeichen direkt vor AAA sein werden, und nach ZZZ dem Teil, den ich an 1234 interessiere.

Mit sed ist es möglich, etwas mit einem String zu tun:

echo "$STRING" | sed -e "s|.*AAA\(.*\)ZZZ.*|\1|"

Und das gibt mir 1234 als Ergebnis.

Wie mache ich das gleiche in Python?

226
miernik

Verwendung von regulären Ausdrücken - Dokumentation zur weiteren Referenz

import re

text = 'gfgfdAAA1234ZZZuijjk'

m = re.search('AAA(.+?)ZZZ', text)
if m:
    found = m.group(1)

# found: 1234

oder:

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'

Wenn Sie möchten, können Sie auch Regexx mit dem re-Modul verwenden. Dies ist jedoch in Ihrem Fall nicht erforderlich. 

87
Lennart Regebro

regulären Ausdruck

import re

re.search(r"(?<=AAA).*?(?=ZZZ)", your_text).group(0)

Der obige Ist-Zustand schlägt mit einer AttributeError fehl, wenn in your_text keine "AAA" und "ZZZ" vorhanden sind

string-Methoden

your_text.partition("AAA")[2].partition("ZZZ")[0]

Das Obige wird eine leere Zeichenfolge zurückgeben, wenn "AAA" oder "ZZZ" nicht in your_text vorhanden sind.

PS-Python-Herausforderung?

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

Sie können re module dafür verwenden:

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

Mit sed ist es möglich, so etwas mit einem String zu machen:

echo "$STRING" | sed -e "s|.*AAA\(.*\)ZZZ.*|\1|"

Und das gibt mir 1234 als Ergebnis.

Sie können dasselbe mit der Funktion re.sub Mit demselben regulären Ausdruck tun.

>>> re.sub(r'.*AAA(.*)ZZZ.*', r'\1', 'gfgfdAAA1234ZZZuijjk')
'1234'

In der Grundeinstellung werden Erfassungsgruppen durch \(..\) dargestellt, in python wurde sie jedoch durch (..) Dargestellt.

5
Avinash Raj

Sie können den ersten Teilstring mit dieser Funktion in Ihrem Code finden (nach Zeichenindex). Sie können auch finden, was hinter einem Teilstring steht. 

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

sie können dies mit nur einer Codezeile tun

>>> import re

>>> re.findall(r'\d{1,5}','gfgfdAAA1234ZZZuijjk')

>>> ['1234']

ergebnis wird Liste erhalten ...

3
mahesh gupta

Nur für den Fall, dass jemand dasselbe tun muss wie ich. Ich musste alles in Klammern in einer Zeile extrahieren. Wenn ich zum Beispiel eine Zeile wie 'US-Präsident (Barack Obama) traf mit ...' und ich möchte nur 'Barack Obama' haben, dann ist dies die Lösung:

regex = '.*\((.*?)\).*'
matches = re.search(regex, line)
line = matches.group(1) + '\n'

Das heißt Sie müssen Klammern mit dem Zeichen slash \ blockieren. Obwohl es ein Problem mit reguläreren Ausdrücken als Python ist.

In einigen Fällen werden vor der Regex-Definition möglicherweise 'r' Symbole angezeigt. Wenn es kein Präfix r gibt, müssen Sie Escape-Zeichen wie in C verwenden. Here wird darüber mehr diskutiert. 

2
wzbozon

In Python kann das Extrahieren der Teilzeichenfolge aus der Zeichenfolge mithilfe der Methode findall im Modul für reguläre Ausdrücke (re) erfolgen.

>>> import re
>>> s = 'gfgfdAAA1234ZZZuijjk'
>>> ss = re.findall('AAA(.+)ZZZ', s)
>>> print ss
['1234']
2
rashok

Überrascht hat das noch niemand erwähnt, was meine schnelle Version für einmalige Skripte ist:

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

Gibt

string
0

Hier ist eine Lösung ohne Regex, die auch Szenarien berücksichtigt, bei denen der erste Teilstring den zweiten Teilstring enthält. Diese Funktion findet nur einen Teilstring, wenn sich der zweite Marker hinter dem ersten Marker befindet.

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