Q:
为什么在多行文本匹配中,使用`[.\n]*?要找的文字`无法正确匹配,而使用`^(.|\n)*?要找的文字`可以?
A:
在正则表达式中,[.\n]和(.|\n)存在根本上的不同,这是导致你的多行匹配结果不同的原因。
[.\n] 是一个字符类,其内部的.字符在字符类中失去了特殊含义,它被当做普通的点字符来对待。所以[.\n]实际上只会匹配一个普通的.字符或者一个换行符 \n,而不是任意字符。
而(.|\n) 使用的是分组和选择结构。这里的.保持其特殊含义,即匹配任意单个字符(除换行符 \n 之外),而| 表示选择,所以(.|\n) 可以匹配任意单个字符,包括换行符 \n。这就是为什么 (.\|\n)* 能够匹配任意数量的任意字符,包括换行符,在多行模式下工作得很好。
对于多行文本,如果你想匹配从开始位置到特定文本的任意字符序列(包括换行符),你应使用类似如下的模式:
^(.|\n)*?要找的文字
或者,如果你的正则表达式引擎支持点号.匹配新行的模式,你可以启用单行模式。在很多正则表达式库中,这可以通过添加一个特定的修饰符来实现,如(?s)在PCRE (Perl Compatible Regular Expressions) 中。例如:
(?s)^.*?要找的文字
最后,如果你不希望使用(?s)这样的修饰符,也可以使用一个通配字符类,它匹配任意字符,包括换行符,例如:
^[\s\S]*?要找的文字
这使用了一个字符类[\s\S],它组合匹配任何空白字符\s和任何非空白字符\S,实际上就匹配了任何可能的字符,包括换行符。
--
FROM 123.119.160.*