2017-02-14 9 views
1

私は文字列内にすべて[[A-Za-z].]+をキャプチャしたいと思います。つまり、アルファベット文字とそれに続くドットのすべての繰り返しです。Python regexモジュールの再帰正規表現ですか?

したがって、たとえば、"ABC A.B.C. UVWX U.V.W.X. XYZ XY.Z."

に私は(彼らは、ドットに続く1つの文字の繰り返しですとして)のみ"A.B.C.""U.V.W.X."を引き出したいと思います。

これを行うには再帰的な正規表現が必要です。[[A-Za-z].]+

これはPythonのreモジュールまたはregexモジュールで実装できますか?

+0

私は再帰がここに右の単語ではないと思います。このアイデアを正確に表現するには、反復がより良い方法になります。 –

答えて

1
この

は、単純なre.findall表記使用して、あなたのために動作します:それは文字列の先頭であれば、私は最初のチェックの正規表現では

(?:(?<=\s)|(?<=^))(?:[A-Za-z]\.)+ 

を、または文字列の前にスペースがある場合には、繰り返し文字+期間を確認します。 https://regex101.com/r/ZwW7c7/4

Pythonのコード(私が書いたこと):

import re 
regex = r"(?:(?<=\s)|(?<=^))(?:[A-Za-z]\.)+" 
string = 'D.E.F. ABC A.B.C. UVWX U.V.W.X. XYZ XY.Z.' 
print(re.findall(regex,string)) 

出力を、私はあなたがそれがここで働く見ることができる私は非キャプチャグループに(?:...)

をキャプチャしたくない部品を配置します:

[ 'DEF'、 'ABC'、 'UVWX']

+1

これは、 'A.B.C XYZ'の先頭にある' A.B.C. 'と一致しません。 – falsetru

+0

あなたは正しいです、私たちは\ sまたは文字列の始めをチェックする必要があります、私は更新されます! –

+1

手動でmatchNumを1増やす必要はありません。 'enumerate'はオプションの' start'パラメータを受け取ります: 'enumerate(matches、1)' – falsetru

1

あなたは境界文字の間にネストされたグループの反復(文字またはドットではありません。この場合は何も)、その後、あなたの試合を定義するために非キャプチャグループを使用し、すべての一致するグループをキャプチャすることができます。

<!-- language: lang-py --> 

import re 

MATCH_GROUPS = re.compile(r"(?:[^a-z.]|^)((?:[a-z]\.)+)(?:[^a-z.]|$)", re.IGNORECASE) 

your_string = "ABC A.B.C. UVWX U.V.W.X. XYZ XY.Z." # get a list of matches 

print(MATCH_GROUPS.findall(your_string)) # ['A.B.C.', 'U.V.W.X.'] 

ちょっと鈍いですが、エッジケースでも仕事を終わらせるべきです。

P.S.複数のリピートだけを探している場合は、上記のように1回の出現にも一致します(例えば、A.)。+(1つ以上のリピート)を任意の範囲に置き換えてください(例:{2,} )。

編集:文字列の境界の始まり/終わりにも一致する小さな変更。

0

(私たちは、文字列の先頭またはスペースの後にある場合、テスト)この正規表現は、仕事をしているようだ:

\A([A-Za-z]\.)+|(?<=\s)([A-Za-z]\.)+ 

編集:申し訳ありませんがショーンはあなたの修正答え

1

を見ていませんpositive look-around assertions使用:

>>> import re 
>>> pattern = r'(?:(?<=\s)|^)(?:[A-Za-z]\.)+(?:(?=\s)|$)' 
>>> re.findall(pattern, 'ABC A.B.C. UVWX U.V.W.X. XYZ XY.Z.') 
['A.B.C.', 'U.V.W.X.'] 
>>> re.findall(pattern, 'A.B.C. UVWX U.V.W.X. XYZ XY.Z.') 
['A.B.C.', 'U.V.W.X.'] 
>>> re.findall(pattern, 'DEF A.B.C. UVWX U.V.W.X.Y') 
['A.B.C.'] 

UPDATEを@bubblebobbleが示唆したように、あなたは正規表現を簡略化することができ負見回すアサーションで(非空白文字)\Sを使用して:

pattern = r'(?<!\S)(?:[A-Za-z]\.)+(?!\S)' 
+1

@bobblebubble、コメントありがとうございます。あなたの正規表現を含めるように答えを更新します。 – falsetru