Python 正则表达式错误地匹配尾随的换行符
Python regex erronously matches trailing newlines
带有结束锚点 ($) 的正则表达式在匹配时完全忽略尾随换行符的存在。
例如
import re
regex = re.compile(r'^$')
text = "\n"
print regex.match(text)
以上代码片段将匹配包含“\n”的文本。由于上面的正则表达式在开始和结束锚点之间没有任何内容,我认为它应该只匹配空字符串。
有什么方法可以解决此问题?
P.S。
上面的代码是一个简化的正则表达式来说明问题。我使用的实际正则表达式是:
re.compile(r'^\S(?:\S| (?!\s)){0,199}$(?<=\S)')
这也匹配包含尾随换行符的文本。
使用 \Z
匹配缓冲区的结尾,使用 \A
匹配缓冲区的开头。
更新:^$
之所以没有如你所愿,是因为匹配$
的规则是:
- 如果缓冲区以换行符结尾
$
匹配最后一个换行符之前
- 否则
$
匹配缓冲区的末尾
如果正则表达式是用 re.MULTLINE
编译的,那么 $
也将匹配任何内部换行符之前的位置。
下面是一些演示这一点的代码:
import re
def showit(r, inp):
ms = r.finditer(inp)
for i,m in enumerate(ms):
print " match", i, " start:", m.start(0), " end:", m.end(0)
print ""
print "regex x$ against x\nx"
showit(re.compile("x$"), "x\nx")
print "regex x$ against x\nx\n"
showit(re.compile("x$"), "x\nx\n")
print "regex x$ re.MULTILINE against x\nx"
showit(re.compile("x$", re.MULTILINE), "x\nx")
输出:
regex x$ against x\nx
match 0 start: 2 end: 3
regex x$ against x\nx\n
match 0 start: 2 end: 3
regex x$ re.MULTILINE against x\nx
match 0 start: 0 end: 1
match 1 start: 2 end: 3
带有结束锚点 ($) 的正则表达式在匹配时完全忽略尾随换行符的存在。
例如
import re
regex = re.compile(r'^$')
text = "\n"
print regex.match(text)
以上代码片段将匹配包含“\n”的文本。由于上面的正则表达式在开始和结束锚点之间没有任何内容,我认为它应该只匹配空字符串。
有什么方法可以解决此问题?
P.S。 上面的代码是一个简化的正则表达式来说明问题。我使用的实际正则表达式是:
re.compile(r'^\S(?:\S| (?!\s)){0,199}$(?<=\S)')
这也匹配包含尾随换行符的文本。
使用 \Z
匹配缓冲区的结尾,使用 \A
匹配缓冲区的开头。
更新:^$
之所以没有如你所愿,是因为匹配$
的规则是:
- 如果缓冲区以换行符结尾
$
匹配最后一个换行符之前 - 否则
$
匹配缓冲区的末尾
如果正则表达式是用 re.MULTLINE
编译的,那么 $
也将匹配任何内部换行符之前的位置。
下面是一些演示这一点的代码:
import re
def showit(r, inp):
ms = r.finditer(inp)
for i,m in enumerate(ms):
print " match", i, " start:", m.start(0), " end:", m.end(0)
print ""
print "regex x$ against x\nx"
showit(re.compile("x$"), "x\nx")
print "regex x$ against x\nx\n"
showit(re.compile("x$"), "x\nx\n")
print "regex x$ re.MULTILINE against x\nx"
showit(re.compile("x$", re.MULTILINE), "x\nx")
输出:
regex x$ against x\nx
match 0 start: 2 end: 3
regex x$ against x\nx\n
match 0 start: 2 end: 3
regex x$ re.MULTILINE against x\nx
match 0 start: 0 end: 1
match 1 start: 2 end: 3