Php Markdown正则表达式中的原子群

Php Markdown正则表达式中的原子群,php,regex,markdown,Php,Regex,Markdown,我正在研究dflydev的MarkdownParser。 在doBlockQuotes中,它们在整个表达式上使用Atmoic组。 我知道Atmoic分组,但我不明白它在这里有什么帮助 为什么会这样: / ( # Wrap whole match in $1 (?> ^[ ]*>[ ]? # ">" at the start of a line .+\n # rest of t

我正在研究dflydev的MarkdownParser。 在doBlockQuotes中,它们在整个表达式上使用Atmoic组。 我知道Atmoic分组,但我不明白它在这里有什么帮助

为什么会这样:

/
(                     # Wrap whole match in $1
    (?>
        ^[ ]*>[ ]?    # ">" at the start of a line
        .+\n          # rest of the first line
        (.+\n)*       # subsequent consecutive lines
        \n*           # blanks
    )+
)
/xm
比这更好的是:

/
(                     # Wrap whole match in $1
        ^[ ]*>[ ]?    # ">" at the start of a line
        .+\n          # rest of the first line
        (.+\n)*       # subsequent consecutive lines
        \n*           # blanks
)
/xm

原子组后面的
+
量词表示正则表达式引擎将尝试匹配组内的模式一次或多次。这与第二个表达式不同,在第二个表达式中,引擎只尝试匹配模式一次

+
后面没有惰性修饰符
,因此它将贪婪地匹配,即尽可能多地匹配

分组可能是原子化的,因为除了使组不被捕获外,它还可以防止在整个子表达式的每次完全匹配之后出现任何回溯

如果或一旦组末尾的
\n*
未能匹配换行符,则由于
+
的原因,引擎将开始尝试从头开始重新匹配组。如果它不能这样做,那么因为组是原子的,所以将返回现有的匹配项

如果组不是原子的,则引擎将回溯以尝试不同的方式匹配刚刚成功匹配的内容,然后再尝试匹配组的开始部分

例如,如果匹配的最后三个字符是换行符,
\n*
,它将首先给出最后一个字符,然后再次尝试匹配组的开头。当失败时,它会给另一个新的队列,然后再试一次,以此类推

回溯将继续到
(.+\n)*
序列,因为
匹配的内容以及
+
*
匹配的字符数都具有灵活性,在尝试进一步匹配之前,将有许多方法使发动机能够匹配模式

字符串的同一部分可以通过许多不同的方式被整个子表达式匹配,因此在引擎确定不可能进行进一步匹配之前,可能会出现大量低效、耗时的回溯


原子组表示法意味着这是可以避免的。

如果您了解原子组,您也应该了解它们在这里的作用。我理解示例,但不理解本文中的示例。。我说的两种表达方式有什么区别?