我正在研究 dflydev 的 MarkdownParser。 在doBlockQuotes line 1167 , 他们在整个表达式中使用了 Atmoic Group。 我知道 Atmoic Grouping 但我不明白它在这里有什么帮助?
这是为什么:
/
( # 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)*
序列,因为 .
匹配的内容和数量的灵 active 字符由 +
和 *
匹配,引擎可以通过多种方式匹配模式,然后再尝试进一步匹配。
字符串的同一部分可以通过许多不同的方式与整个子表达式匹配,因此在引擎确定不可能进行进一步的匹配之前,可能会进行大量低效、耗时的回溯。
原子组表示意味着可以避免这种情况。
关于php - Markdown 正则表达式中的原子组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14662785/