12

これは本当に簡単な質問のように感じますが、私はどこにも答えを見つけることができません。

(注:私はPythonを使用していますが、これは問題ではありません。)

次の文字列があるとします。

s = "foo\nbar\nfood\nfoo"

「food」の「foo」の直後に改行または末尾が続かないという事実に基づいて、「foo」の両方のインスタンスに一致するが「food」には一致しない正規表現を見つけようとしているだけです。ストリング。

これはおそらく私の質問を表現するための非常に複雑な方法ですが、それは作業するための具体的な何かを与えます。

これが私が試したことのいくつかと結果です(注:私が望む結果は[ foo\nfoo]です):

foo[\n\Z] => [ 'foo\n']

foo(\n\Z) => [ '\n'''] <=これは改行とEOSに一致するようですが、foo

foo($|\n) => [ '\n''']

(foo)($|\n) => [(foo'\n')、(foo'')] <=ほぼそこにあり、これは使用可能なプランBですが、完璧な解決策を見つけたいと思います。

私が見つけた唯一の機能は次のとおりです。

foo$|foo\n => [ 'foo\n'、 `'foo']

これは、このような単純な例では問題ありませんが、はるかに大きな式で扱いにくくなる可能性があることは簡単にわかります(もちろん、これfooは私が実際に使用している大きな式の代わりになります)。


興味深いことに、私の問題に最も近いSOの質問は、これでした。正規表現では、文字列の末尾または特定の文字のいずれかに一致します。

\nここでは、「特定の文字」を単純に置き換えることができます。現在、受け入れられた回答は正規表現を使用してい/(&|\?)list=.*?(&|$)/ます。OPがJavaScriptを使用している(質問はタグでタグ付けされているjavascript)ので、JavaScript正規表現インタープリターが異なる可能性がありますが、Pythonで上記の正規表現を使用して質問で指定された正確な文字列を使用すると、悪い結果が得られます。

>>> findall("(&|\?)list=.*?(&|$)", "index.php?test=1&list=UL")
[('&', '')]
>>> findall("(&|\?)list=.*?(&|$)", "index.php?list=UL&more=1")
[('?', '&')]

だから、私は困惑しています。

4

3 に答える 3

11
>>> import re
>>> re.findall(r'foo(?:$|\n)', "foo\nbar\nfood\nfoo")
['foo\n', 'foo']

(?:...)非キャプチャグループを作成します。

これは、(reモジュールリファレンスから)次の理由で機能します。

re.findall(pattern、string、flags = 0)

文字列のリストとして、文字列内のパターンの重複しない一致をすべて返します。文字列は左から右にスキャンされ、一致するものが見つかった順序で返されます。パターンに1つ以上のグループが存在する場合は、グループのリストを返します。パターンに複数のグループがある場合、これはタプルのリストになります。空の試合は、別の試合の開始に触れない限り、結果に含まれます。

于 2012-12-31T16:55:17.487 に答える
4

パターンのre.MULTILINEオプションの改行を使用して含めることができます。$

s = "foo\nbar\nfood\nfoo"
pattern = re.compile('foo$\n?', re.MULTILINE)
print re.findall(pattern, s)
# -> ['foo\n', 'foo']
于 2012-12-31T16:49:13.657 に答える
1

あなただけに関心がある場合foo

In [42]: import re

In [43]: strs="foo\nbar\nfood\nfoo"

In [44]: re.findall(r'\bfoo\b',strs)
Out[44]: ['foo', 'foo']

\bisは単語の境界を示します。

\b

空の文字列に一致しますが、単語の最初または最後にのみ一致します。単語は英数字またはアンダースコア文字のシーケンスとして定義されるため、単語の終わりは空白または英数字以外のアンダースコア文字で示されます。正式には、\bは\wと\W文字の間(またはその逆)、または\ wと文字列の先頭/末尾の間の境界として定義されるため、英数字と見なされる文字の正確なセットは次のようになります。 UNICODEフラグとLOCALEフラグの値について。たとえば、r'\ bfoo \b'は'foo'、'foo。'、'(foo)'、'bar foo baz'と一致しますが、'foobar'または'foo3'とは一致しません。文字範囲内では、Pythonの文字列リテラルとの互換性のために、\bはバックスペース文字を表します。

出典

于 2012-12-31T16:38:37.280 に答える