Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/github/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 原子团透明度_Regex_Pcre_Backtracking - Fatal编程技术网

Regex 原子团透明度

Regex 原子团透明度,regex,pcre,backtracking,Regex,Pcre,Backtracking,以这个正则表达式为例 a*b (?>a*)b 如果aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 这需要调试器中的67步骤失败 现在考虑这个正则表达式。< /P> a*b (?>a*)b 如果aaaaaaaaaaa

以这个正则表达式为例

a*b
(?>a*)b
如果
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

这需要调试器中的
67
步骤失败

现在考虑这个正则表达式。< /P>

a*b
(?>a*)b
如果
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

这需要调试器中的
133
步骤失败

最后,这个正则表达式:

a*+b  (a variant of atomic group)
如果
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

这需要调试器中的
67
步骤失败

当我检查基准
原子组(?>a*)时,b
执行
179%
更快

现在原子组禁用回溯。所以在比赛中表现不错

  • 但为什么要多走几步呢?有人能解释一下吗

  • 为什么在两个原子群
    (?>a*)b
    a*+b
    之间存在步进差异

  • 它们的工作方式不同吗?

    那么什么是回溯呢? 引擎出现默认贪婪的量词。贪婪修饰符根据需求匹配所有可能的和回溯,允许高效匹配

    引用人:

    贪婪的量词首先尽可能匹配。因此,
    *
    匹配整个字符串。然后匹配器尝试匹配下面的
    f
    ,但没有剩余字符。因此它“回溯”,使贪婪的量词少匹配一个东西(使字符串末尾的“o”不匹配)。这仍然与正则表达式中的
    f
    不匹配,因此它又“回溯”了一步,使贪婪的量词再次匹配更少的东西(使字符串末尾的“oo”不匹配)。这仍然与正则表达式中的
    f
    不匹配,因此它又返回了一个步骤(使字符串末尾的“foo”不匹配)。现在,匹配器最终匹配正则表达式中的
    f
    ,并且
    o
    和下一个
    o
    也被匹配。成功![……]

    这与
    a*+b
    有什么关系? 在
    /a*+b/
    中:

    • a
      文字字符“a”
    • *+
      零或更多,所有格
    • b
      文本字符“b”
    引用人:

    所有格量词就像贪婪量词一样,但它不会后退。因此,它从匹配整个字符串开始,不留下任何不匹配的内容。那么它就没有什么东西可以与正则表达式中的
    f
    匹配了。由于所有格量词没有回溯,因此匹配失败

    为什么这很重要? 机器无法意识到自己是否在进行有效匹配。请参阅此处以获取一个合适的示例:。在许多场景中,快速编写的正则表达式可能效率不高,并且在部署中很容易出现问题

    那么什么是原子团? 在原子组内的模式完成匹配后,它永远不会放弃。研究这个例子:

    Pattern: (?>\d\w{2}|12)c
    Matching string: 12c
    
    看起来完全合法,但此匹配失败。步骤很简单:原子组的第一次交替完全匹配-
    \d\w{2}
    消耗
    12c
    。然后该组完成匹配-现在是指针位置:

    Pattern: (?>\d\w{2}|12)c
                       ^
    Matching string: 12c
                        ^
    
    这种模式在发展。现在我们尝试匹配
    c
    ,但是没有
    c
    。匹配失败,而不是尝试回溯(释放
    \d\w{2}
    并使用
    12

    那是个坏主意!我们为什么要阻止回溯,单面体? 现在假设我们正在使用JSON对象进行操作。这个文件不小。从最后开始回溯是个坏主意

           "2597401":[{"jobID":"2597401",
                     "account":"TG-CCR120014",
                     "user":"charngda",
                     "pkgT":{"pgi/7.2-  5":{"libA":["libpgc.so"],
                     "flavor":["default"]}},          
                     "startEpoch":"1338497979",
                     "runTime":"1022",
                     "execType":"user:binary",              
                     "exec":"ft.D.64",
                     "numNodes":"4",
                     "sha1":"5a79879235aa31b6a46e73b43879428e2a175db5",
                     "execEpoch":1336766742,
                     "execModify":"Fri May 11 15:05:42 2012",
                     "startTime":"Thu May 31 15:59:39 2012",
                     "numCores":"64",
                     "sizeT":{"bss":"1881400168","text":"239574","data":"22504"}},  
                     {"jobID":"2597401",
                     "account":"TG-CCR120014",
                     "user":"charngda",
                     "pkgT":{"pgi/7.2-5":{"libA":["libpgc.so"],
                     "flavor":["default"]}},
                     "startEpoch":"1338497946",
                     "runTime":"33"  "execType":"user:binary",
                     "exec":"cg.C.64",
                     "numNodes":"4",
                     "sha1":"caf415e011e28b7e4e5b050fb61cbf71a62a9789",
                     "execEpoch":1336766735,
                    "execModify":"Fri May 11 15:05:35 2012",
                    "startTime":"Thu May 31 15:59:06 2012",
                    "numCores":"64",
                    "sizeT":{"bss":"29630984","text":"225749","data":"20360"}},
                    {"jobID":"2597401",
                    "account":"TG-CCR120014",
                    "user":"charngda",
                    "pkgT":{"pgi/7.2-5":  {"libA":["libpgc.so"],
                    "flavor":["default"]}},
                    "startEpoch":"1338500447",
                    "runTime":"145",
                    "execType":"user:binary",
                    "exec":"mg.D.64",
                    "numNodes":"4",
                    "sha1":"173de32e1514ad097b1c051ec49c4eb240f2001f",
                    "execEpoch":1336766756,
                    "execModify":"Fri May 11 15:05:56 2012",
                    "startTime":"Thu May 31 16:40:47 2012",
                    "numCores":"64",
                    "sizeT":{"bss":"456954120","text":"426186","data":"22184"}},{"jobID":"2597401",
                    "account":"TG-CCR120014",
                    "user":"charngda",
                    "pkgT":{"pgi/7.2-5":{"libA":["libpgc.so"],
                    "flavor":["default"]}},
                    "startEpoch":"1338499002",
                    "runTime":"1444",
                    "execType":"user:binary",
                    "exec":"lu.D.64",
                    "numNodes":"4",
                    "sha1":"c6dc16d25c2f23d2a3321d4feed16ab7e10c2cc1",
                    "execEpoch":1336766748,
                    "execModify":"Fri May 11 15:05:48 2012",
                    "startTime":"Thu May 31 16:16:42 2012",
                    "numCores":"64",
                    "sizeT":{"bss":"199850984","text":"474218","data":"27064"}}],
    
    啊哦

    你明白我的意思了吗P

    我会让你们去弄清楚剩下的,试着找出更多关于所有格量词和原子群的信息;我没有在这篇文章里写任何其他东西。这就是JSON的来源,几天前我看到了答案,非常鼓舞人心:

    同时阅读
    我觉得有点不对劲。。。 我不知道您是如何进行基准测试的,但是
    a*+b
    (?>a*)b
    应该是相同的。引用(我的重点):

    基本上,不是写
    X*+
    ,而是写
    (?>X*)
    。需要注意的是,量化标记
    X
    和量词都位于原子组内。即使
    X
    是一个组,您仍然需要在其周围放置一个额外的原子组以实现相同的效果
    (?:a | b)*+
    等同于
    (?>(?:a | b)*)
    ,但不等同于
    (?>a | b)*
    。后者是一个有效的正则表达式,但当作为更大的正则表达式的一部分使用时,它不会有相同的效果

    为了确认上述内容,我在上运行了以下命令:

    现在,我绝不是一个PHP专家,所以我不知道这是否是对其中的内容进行基准测试的正确方法,但这是因为它们都具有相同的性能,考虑到任务的简单性,这是一种预期

    尽管如此,我还是从上面注意到了几件事:

    (?>a)*b
    (?>a*)b
    都比另一个正则表达式快179%;以上各项之间的差距均在7%以内

    回到实际问题上来 但为什么要多走几步呢?有人能解释一下吗

    需要注意的是,步骤的数量并不能直接表示正则表达式的性能。这是一个因素,但不是最终决定因素。有更多的步骤,因为细分在进入组之前有步骤,而在进入组之后

    1   / (?> a* ) b/x    aaaaaaaaaaaaaaaaaaaa...
         ^
    2   / (?> a* ) b/x    aaaaaaaaaaaaaaaaaaaa...
          ^^^^^^^^
    3   / (?> a* ) b/x    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac
              ^^
    4   / (?> a* ) b/x    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac
                ^
    5   / (?> a* ) b/x    aaaaaaaaaaaaaaaaaaaaa...
                   ^
    
    因为团队的原因,这比3个步骤多了2个步骤

    1   / a*+ b /x    aaaaaaaaaaaaaaaaaaaa...
         ^
    2   / a*+ b /x    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac
          ^^^
    3   / a*+ b /x    aaaaaaaaaaaaaaaaaaaaa...
              ^
    
    其中,您可以说
    a*b
    (?:a*)b
    相同,但后者有更多步骤:

    1   / (?: a* ) b/x    aaaaaaaaaaaaaaaaaaaa...
         ^
    2   / (?: a* ) b/x    aaaaaaaaaaaaaaaaaaaa...
          ^^^^^^^^
    3   / (?: a* ) b/x    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac
              ^^
    4   / (?: a* ) b/x    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac
                ^
    5   / (?: a* ) b/x    aaaaaaaaaaaaaaaaaaaaa...
    
    注意:即使在这里,您也可以看到regex101具有步骤optimis
    Pattern 1: (?:c)at
    Pattern 2: cat