Jak wyodrębnić podłańcuch między dwoma znacznikami?
Załóżmy, że mam Ciąg 'gfgfdAAA1234ZZZuijjk'
i chcę wyodrębnić tylko '1234'
część.
Wiem tylko, co będzie kilka znaków bezpośrednio przed AAA
, a po ZZZ
część, która mnie interesuje 1234
.
Z sed
można zrobić coś takiego za pomocą ciągu znaków:
echo "$STRING" | sed -e "s|.*AAA\(.*\)ZZZ.*|\1|"
I to da mi 1234
w rezultacie.
Jak zrobić to samo w Pythonie?
12 answers
Używanie wyrażeń regularnych- Dokumentacja dla dalszego odniesienia
import re
text = 'gfgfdAAA1234ZZZuijjk'
m = re.search('AAA(.+?)ZZZ', text)
if m:
found = m.group(1)
# found: 1234
Lub:
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-08 15:50:59
>>> s = 'gfgfdAAA1234ZZZuijjk'
>>> start = s.find('AAA') + 3
>>> end = s.find('ZZZ', start)
>>> s[start:end]
'1234'
Następnie możesz używać wyrażeń regularnych z modułem re, jeśli chcesz, ale nie jest to konieczne w Twoim przypadku.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-12 09:17:23
Wyrażenie regularne
import re
re.search(r"(?<=AAA).*?(?=ZZZ)", your_text).group(0)
Powyższe as-is zawiedzie z AttributeError
jeśli nie ma "AAA" i "ZZZ" w your_text
Metody łańcuchowe
your_text.partition("AAA")[2].partition("ZZZ")[0]
Powyższe zwróci pusty łańcuch, jeśli" AAA " lub " ZZZ " nie istnieją w your_text
.
PS Python Challenge?
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-06 23:43:17
import re
print re.search('AAA(.*?)ZZZ', 'gfgfdAAA1234ZZZuijjk').group(1)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-12 09:18:00
Możesz użyć Re moduł do tego:
>>> import re
>>> re.compile(".*AAA(.*)ZZZ.*").match("gfgfdAAA1234ZZZuijjk").groups()
('1234,)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-12 09:19:21
Z sed można zrobić coś takiego za pomocą łańcucha:
echo "$STRING" | sed -e "s|.*AAA\(.*\)ZZZ.*|\1|"
To da mi 1234.
Możesz zrobić to samo z re.sub
funkcją używając tego samego wyrażenia regularnego.
>>> re.sub(r'.*AAA(.*)ZZZ.*', r'\1', 'gfgfdAAA1234ZZZuijjk')
'1234'
W podstawowym sed Grupa przechwytywania jest reprezentowana przez \(..\)
, ale w Pythonie była reprezentowana przez (..)
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-31 08:29:21
Możesz znaleźć pierwszy podłańcuch z tą funkcją w kodzie (według indeksu znaków). Ponadto, można znaleźć to, co jest po podłańcuchu.
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]))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-21 05:38:35
Na wypadek, gdyby ktoś musiał zrobić to samo, co ja. Musiałem wyodrębnić wszystko wewnątrz nawiasu w linii. Na przykład, jeśli mam linię jak " prezydent USA (Barack Obama) spotkał się z ... a ja chcę dostać tylko 'Baracka Obamę' to jest rozwiązanie:
regex = '.*\((.*?)\).*'
matches = re.search(regex, line)
line = matches.group(1) + '\n'
Czyli musisz zablokować nawias za pomocą znaku slash \
. Chociaż jest to problem o więcej wyrażeń regularnych, że Python.
Ponadto, w niektórych przypadkach możesz zobaczyć symbole 'r' przed definicją regex. Jeśli nie ma r prefiks, musisz użyć znaków escape, jak w C. Tutaj jest więcej dyskusji na ten temat.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:07
Możesz to zrobić używając tylko jednej linijki kodu
>>> import re
>>> re.findall(r'\d{1,5}','gfgfdAAA1234ZZZuijjk')
>>> ['1234']
Wynik otrzyma listę...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-11 11:39:55
>>> s = '/tmp/10508.constantstring'
>>> s.split('/tmp/')[1].split('constantstring')[0].strip('.')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-11 09:23:44
W Pythonie, ekstrakcję fragmentu łańcucha można wykonać metodą findall
w module wyrażenia regularnego (re
).
>>> import re
>>> s = 'gfgfdAAA1234ZZZuijjk'
>>> ss = re.findall('AAA(.+)ZZZ', s)
>>> print ss
['1234']
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-14 09:11:23
Jeden Liner, który zwraca inny łańcuch, jeśli nie było dopasowania.
Edit: ulepszona wersja używa funkcji next
, w razie potrzeby zastąp "not-found"
czymś innym:
import re
res = next( (m.group(1) for m in [re.search("AAA(.*?)ZZZ", "gfgfdAAA1234ZZZuijjk" ),] if m), "not-found" )
Moja inna metoda aby to zrobić, mniej optymalna, używa regex 2nd time, nadal nie znalazłem krótszego sposobu:
import re
res = ( ( re.search("AAA(.*?)ZZZ", "gfgfdAAA1234ZZZuijjk") or re.search("()","") ).group(1) )
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-03 18:31:44