无法找到正确的正则表达式语法来匹配换行符或字符串结尾

Ken*_*ows 12 python regex newline

这感觉就像一个非常简单的问题,但我无法在任何地方找到答案.

(注意:我使用的是Python,但这不重要.)

说我有以下字符串:

s = "foo\nbar\nfood\nfoo"
Run Code Online (Sandbox Code Playgroud)

我只是试图找到一个匹配两个"foo"实例的正则表达式,而不是"食物",基于"食物"中的"foo"不会立即跟在换行符或结束时串.

这可能是表达我的问题的一种过于复杂的方式,但它提供了一些具体的工作方式.

以下是我尝试的一些事情,结果(注意:我想要的结果是[ foo\n,foo]):

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东西是我实际使用的更大表达式的代表).


有趣的是:我能找到的最接近的问题是这个问题:在正则表达式中,匹配字符串的结尾或特定的字符

在这里,我可以简单地替换\n我的"特定角色".现在,接受的答案使用正则表达式/(&|\?)list=.*?(&|$)/.我注意到OP使用的是JavaScript(问题是用javascript标签标记的),所以也许JavaScript正则表达式解释器不同,但是当我在Python中使用上述正则表达式中的问题中给出的确切字符串时,我得到的结果很糟糕:

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

所以,我很难过.

Phi*_*ost 10

>>> import re
>>> re.findall(r'foo(?:$|\n)', "foo\nbar\nfood\nfoo")
['foo\n', 'foo']
Run Code Online (Sandbox Code Playgroud)

(?:...)成为一个非捕获组.

这是因为(来自re模块引用):

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

返回字符串中pattern的所有非重叠匹配,作为字符串列表.从左到右扫描字符串,并按找到的顺序返回匹配项.如果模式中存在一个或多个组,则返回组列表; 如果模式有多个组,这将是一个元组列表.结果中包含空匹配,除非它们触及另一个匹配的开头.

  • 如果普通组中有“$|\n”,则将匹配(并且仅匹配)换行符(因为捕获组中没有其他内容)。您也可以将 foo 放入一个组中,但随后您将再次得到换行符的额外组结果。 (2认同)

omz*_*omz 6

您可以在模式中的后面使用re.MULTILINE并包含可选的换行符:$

s = "foo\nbar\nfood\nfoo"
pattern = re.compile('foo$\n?', re.MULTILINE)
print re.findall(pattern, s)
# -> ['foo\n', 'foo']
Run Code Online (Sandbox Code Playgroud)

  • 大多数正则表达式引擎支持多行选项。您还可以将其直接嵌入到模式中:`re.findall('(?m)foo$\n?', s)`。 (3认同)