perl regex,不匹配的匹配以某种方式不被尊重?

加百列

为什么此正则表达式在以下代码的代码前添加许可证file.hpp

perl -i -0pe 's@(.*\n)*?#ifndef@//LICENSE#ifndef@' file.hpp

和:

    # -0: reads the file into ram (changes file spereator)
    # -p: reads line by line
    # -e: command execution
    # -i: modifiy input directly

file.hpp(带有Unicode BOM的UTF-8):

#ifndef GAGA
#define GAGA
asd
asd
#ifndef NDEBUG

结果是

LICENSE#ifndef NDEBUG

我不明白为什么非贪婪(.*\n)*?匹配直到NDEBUG行?为什么?

用户名

为了使问题更容易重现,下面是一个测试案例,文件内容为字符串:

$_ = "\xef\xbb\xbf#ifndef GAGA\n#define GAGA\nasd\nasd\n#ifndef NDEBUG\n";
s@(.*\n)*?#ifndef@//LICENSE#ifndef@;
print $_

它输出以下内容:

//LICENSE#ifndef NDEBUG

表示正则表达式与字符串的大部分匹配: "\xef\xbb\xbf#ifndef GAGA\n#define GAGA\nasd\nasd\n#ifndef"

为什么要匹配而不是其他?首先,请注意,正则表达式不能仅"\xef\xbb\xbf#ifndef"因为以下原因而匹配

  • 如果带括号的组匹配0次,则没有任何"\xef\xbb\xbf"部分可以匹配
  • 如果带括号的组至少匹配1次,则匹配项必须包含一个 "\n"

其次,regexp会匹配以开头的长字符串,"\xef\xbb\xbf"而不是稍后输入的一些较短的字符串,因为regexp倾向于将匹配开始于尽可能接近输入字符串开头的位置,并且此首选项要强于贪婪/不贪婪。任何单个的量词。如果在字符串开头找到匹配项,则regexp引擎不会继续查找。从字符串的后面开始,它将找不到其他可能的匹配项,从而使非贪婪的量词变得“更快乐”。

因此,总的来说,正则表达式以字符串的开头开始,尝试将非贪婪的括号组匹配0次,发现它不起作用,(因为"\xef"不是"#"),尝试将其匹配1次,找到那是行不通的(因为"#define"is不是"#ifndef"),依此类推,直到最终找到与它匹配4次的作品,然后停止。4是导致字符串开头匹配的非贪婪部分的最小重复次数。

对于处理UTF-8 BOM的诅咒,我的首选策略是在执行其他任何操作之前先将其剥离。

$_ = "\xef\xbb\xbf#ifndef GAGA\n#define GAGA\nasd\nasd\n#ifndef NDEBUG\n";
s/^\xef\xbb\xbf//;
s@(.*\n)*?#ifndef@//LICENSE#ifndef@;
print $_

您可以将这些替换合并到一个操作中,但是我喜欢简单的方法,s/^\xef\xbb\xbf//;因为我可以将其放入几乎任何脚本中-几乎在任何行上!-最坏的情况是什么也没有做,最多只能修复错误。

旁注:您应使用-0777全文件格式。-0单独将分隔符更改为,"\0"如果文件包含NUL,它将不会执行您想要的操作。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Perl Regex匹配某些内容,但请确保匹配字符串不包含字符串

来自分类Dev

Perl否定查找,不匹配单词

来自分类Dev

Perl-SHA1与PHP不匹配

来自分类Dev

Perl-SHA1与PHP不匹配

来自分类常见问题

当Perl与Perl不匹配时,请在和的每行删除“ ^ M”

来自分类Dev

当Perl与Perl不匹配时,请在和的每行删除“ ^ M”

来自分类Dev

Perl和Regex-单行模式匹配

来自分类Dev

在Perl中匹配IP

来自分类Dev

PERL:匹配多种模式

来自分类Dev

perl匹配并删除行数

来自分类Dev

Perl:匹配大型数组

来自分类Dev

在Perl中匹配IP

来自分类Dev

Perl匹配和转换

来自分类Dev

匹配多个结果perl

来自分类Dev

Perl文件路径匹配

来自分类Dev

从行尾匹配 perl 模式

来自分类Dev

Perl:regx 模式匹配

来自分类Dev

Perl regex有效的方式来保持匹配子字符串?

来自分类Dev

Perl:不包含PATTERN的匹配字符串

来自分类Dev

Eclipse:Perl EPIC调试和发布模式执行不匹配

来自分类Dev

正则表达式在Perl中不匹配

来自分类Dev

Perl正则表达式与\ w +不匹配

来自分类Dev

\ w与Perl中的西里尔字符不匹配

来自分类Dev

在perl或sed中默认不匹配的反向引用

来自分类Dev

Perl:不包含PATTERN的匹配字符串

来自分类Dev

正则表达式在Perl中不匹配

来自分类Dev

C程序的perl匹配功能

来自分类Dev

perl regex:将多个匹配项作为变量

来自分类Dev

无法使用perl和regex在阵列中保存模式匹配