web-dev-qa-db-ja.com

2つのマーカー間の部分文字列を抽出する方法

'gfgfdAAA1234ZZZuijjk'という文字列があり、'1234'部分だけを抽出したいとしましょう。

私はAAAの直前と、私が1234に興味を持っている部分のZZZの直後の何文字かを知っているだけです。

sedでは、文字列を使って次のようなことができます。

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

そしてこれは結果として私に1234を与えるでしょう。

Pythonで同じことをするにはどうすればいいですか?

239
miernik

正規表現を使う - ドキュメンテーション さらなる参考のために

import re

text = 'gfgfdAAA1234ZZZuijjk'

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

# found: 1234

または

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
431
eumiro
>>> s = 'gfgfdAAA1234ZZZuijjk'
>>> start = s.find('AAA') + 3
>>> end = s.find('ZZZ', start)
>>> s[start:end]
'1234'

そうすれば、reモジュールでregexpsを使うこともできますが、それは必要ではありません。

90
Lennart Regebro

正規表現

import re

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

your_textに "AAA"と "ZZZ"がない場合、上記のままではAttributeErrorで失敗します。

文字列メソッド

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

your_textに "AAA"または "ZZZ"が存在しない場合、上記は空の文字列を返します。

PS Pythonの挑戦?

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

そのために re moduleを使うことができます。

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

Sedでは、文字列を使って次のようなことができます。

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

そしてこれは結果として私に1234を与えるでしょう。

同じ正規表現を使ってre.sub関数でも同じことができます。

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

基本的なsedでは、キャプチャリンググループは\(..\)で表されますが、pythonでは(..)で表されました。

5
Avinash Raj

1行のコードで実行できます

>>> import re

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

>>> ['1234']

結果はリストを受け取ります...

5
mahesh gupta

あなたはあなたのコードの中でこの関数を使って最初の部分文字列を見つけることができます(文字インデックスによって)。また、サブストリングの後に何があるのか​​を見つけることができます。

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

Pythonでは、文字列から部分文字列を抽出することは、正規表現(findall)モジュールのreメソッドを使って行うことができます。

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

誰もこれについて言及していないことに驚きました。

>>> x = 'gfgfdAAA1234ZZZuijjk'
>>> x.split('AAA')[1].split('ZZZ')[0]
'1234'
2
Uncle Long Hair
>>> s = '/tmp/10508.constantstring'
>>> s.split('/tmp/')[1].split('constantstring')[0].strip('.')
2
user1810100

誰かが私と同じことをしなければならない場合に備えて。括弧内の行をすべて抽出する必要がありました。たとえば、「米国大統領(バラクオバマ)に会った...」などの行があり、「バラクオバマ」だけを取得したい場合、これは解決策です。

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

つまりslash \記号で括弧をブロックする必要があります。 Pythonよりも正規表現に関する問題ですが。

また、場合によっては、正規表現の定義の前に「r」記号が表示されることがあります。接頭辞rがない場合は、Cのようなエスケープ文字を使用する必要があります。 Here でさらに詳しく説明しています。

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

与える

string
0

これは正規表現なしの解決策で、最初の部分文字列に2番目の部分文字列が含まれるシナリオも考慮します。この関数は、2番目のマーカーが最初のマーカーの後にある場合にのみサブストリングを見つけます。

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