在Python正则表达式中,如何匹配包括换行符在内的任意字符,但只在子表达式中匹配而非全局匹配?

101
我想使用re.MULTILINE不要re.DOTALL,这样我就可以拥有一个正则表达式,既包含“任何字符”通配符,又包含正常的.通配符,但它不匹配换行符。是否有方法可以做到这一点?在那些我想包括换行符的情况下,我应该使用什么来匹配任何字符?

2
只需像 [\s\S][\w\W] 这样做即可。 - R Nar
2
[^\r\n] 的意思是除了回车和换行符以外的任何字符。 - Paulo Scardine
嗨,Jason,除非我漏掉了什么,“python”+“regex”可以从标签中推断出来,因此不需要在标题中指定(根据“标题中无标签”的指导方针)? - Matt
3
因为SO的相关问题列表不包括标签,所以上下文信息非常重要。 - Jason S
4
“标题中不要出现标签”这一规定,可以调整为指导方针(而非必须遵守的要求),或者需要重新审视,或者Stack Overflow需要在相关问题列表中显示标签。 - Jason S
2个回答

143

为了匹配换行符或者“任何符号”,在没有使用re.S/re.DOTALL的情况下,可以使用以下任意一种方法:

  1. (?s). - 使用带有s标志的inline modifier group设置一个范围,在该范围内所有的.模式都匹配包括换行符在内的所有字符。

  2. 以下是一些解决方法:

[\s\S]
[\w\W]
[\d\D]

主要思想是字符类中的相反简写类匹配输入字符串中的任何符号。与使用交替语句的(.|\s)和其他变体相比,字符类解决方案更加高效,因为它涉及更少的回溯(当与*+量词一起使用时)。比较一个小例子:需要(?:.|\n)+ 45步才能完成,而只需[\s\S]+ 2步即可完成。请参见Python演示,其中我匹配了以123开头并一直到行首第一个3出现并包括该行的其余部分的行。
import re
text = """abc
123
def
356
more text..."""
print( re.findall(r"^123(?s:.*?)^3.*", text, re.M) )
# => ['123\ndef\n356']
print( re.findall(r"^123[\w\W]*?^3.*", text, re.M) )
# => ['123\ndef\n356']

1
太棒了,谢谢!我知道有一种方法可以做到,但是想不起来了。 - Jason S
修正了一些拼写错误。对此表示抱歉。 - Wiktor Stribiżew
1
@IoannisFilippidis 您建议使用正则表达式选项来匹配任何字符。这超出了当前帖子的范围,因为 OP 已经知道了正则表达式选项,包括 re.Mre.S/re.DOTALL,但是希望知道如何在不使用标志的情况下进行匹配。此外,在 Python re 中,re.MULTILINE 是一个错误的标志,因为它只修改了 ^$ 锚点的行为,而 re.Sre.DOTALL 使 . 匹配任何字符,包括换行符。 - Wiktor Stribiżew
1
@WiktorStribiżew,将此答案的链接放在您的个人资料中,对于像我这样的正则表达式新手来说,这句话“永远不要使用(.|\n)!!!”非常有用。 - pault

11

匹配任何字符(包括换行符):

正则表达式:(注意空格“ ”的使用也在其中)

[\S\n\t\v ]

例子:

import re

text = 'abc def ###A quick brown fox.\nIt jumps over the lazy dog### ghi jkl'
# We want to extract "A quick brown fox.\nIt jumps over the lazy dog"
matches = re.findall('###[\S\n ]+###', text)
print(matches[0])
'matches[0]'将包含:
“一个快速的棕色狐狸。 \n 它跳过懒惰的狗”

'\S' Python文档的描述:

\S 匹配任何非空格字符。

(参见:https://docs.python.org/3/library/re.html#regular-expression-syntax)


这与\t\v不匹配。 - ApproachingDarknessFish
\v 并不经常使用,但我还是包含了它。问题要求匹配“包括换行符在内的任何字符”。所以无论对他来说哪种方式都可以 :-) @ApproachingDarknessFish - Ali Sajjad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接