【问题标题】:backtracking steps for the ending x/结束 x/ 的回溯步骤
【发布时间】:2023-04-09 01:50:01
【问题描述】:

我正在阅读 Jeffrey Friedl 的《Mastering Regular Expressions 3rd Ed》一书。在第 274 页,Jeffrey 要求他的读者调查为什么正则表达式 /x([^/]|[^x]/)*x/ 匹配字符串(匹配的字符以粗体标记)“years =天 /x 除以 x//365;/x 假定为非闰年 x/"。

我从正则表达式中删除了结尾 x/。所以正则表达式 /x([^/]|[^x]/)* 的输出是 "/x 除 x//365; "。但是在我添加了 x/ 之后,正则表达式 /x([^/]|[^x]/)*x/ 的输出是 "/ x 除 x//365;/x 假设为非闰年 x/"

谁能告诉我 Perl 的正则表达式引擎对结尾 x/ 的回溯步骤?

这是我针对这个问题的 perl 脚本。

my $str = "years = days /x divide x//365; /x assume non-leap year x/";
if ($str =~ m{(/x([^/]|[^x]/)*)}) {
    print "\$1: '$1'\n"; # output: $1: '/x divide x//365; '
} else {
    print "not matched.\n";
}


$str = "years = days /x divide x//365; /x assume non-leap year x/";
if ($str =~ m{(/x([^/]|[^x]/)*x/)}) {
    print "\$1: '$1'\n"; # output: $1: '/x divide x//365; /x assume non-leap year x/'
} else {
    print "not matched.\n";
}

【问题讨论】:

    标签: regex


    【解决方案1】:

    这是纲要:

    /x - 匹配 / 后跟 x
    ([^/]|[^x]/)* - 匹配任何不是 a /,或者不是 x 后跟斜线 - 尽可能多次
    x/ - 匹配 x 后跟 /

    所以基本上它是这样说的:以/x 开头,然后匹配除x/ 之外的所有内容,最后以x/ 结束。

    【讨论】:

    • 但匹配的字符串包含多个斜杠(/)。那为什么呢?
    • 当正则表达式引擎遇到/时,它会陷入下一个选择:匹配一个非x字符后跟一个/(例如“//”或“/”) .这将匹配所有内容,直到它不能满足任何一种选择,并且将在x/ 上关闭。
    • 我从正则表达式中删除了结尾的“x/”。所以正则表达式 "/x([^/]|[^x]/)*" 的输出是 "/x 除 x//365; "。但是在我加回“x/”之后,正则表达式 "/x([^/]|[^x]/)*x/" 的输出是 "/x 除 x //365; /x 假设非闰年 x/".你能告诉我正则表达式引擎的回溯步骤吗?
    【解决方案2】:

    我明白了。约瑟夫是对的。当第二个“/x”匹配失败时,正则引擎回溯到“/x”试一试,成功了。

    【讨论】:

      猜你喜欢
      • 2020-02-22
      • 1970-01-01
      • 1970-01-01
      • 2014-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多