非贪婪正则表达式或否定字符 class 哪个更好?
Which would be better non-greedy regex or negated character class?
我需要从字符串 @anything_here@dhhhd@shdjhjs@
中匹配 @anything_here@
。所以我使用了以下正则表达式。
^@.*?@
或
^@[^@]*@
两种方法都行,但我想知道哪种方法更好。具有非贪婪重复的正则表达式或具有否定字符的正则表达式 class?
显然 ^@[^@]*@
选项要好得多。
否定字符 class 被量化 greedily 这意味着正则表达式引擎会立即抓取除 @
之外的 0 个或更多字符,尽可能多.参见 this regex demo 并匹配:
当您使用惰性点匹配模式时,引擎会匹配 @
,然后尝试匹配结尾的 @
(跳过 .*?
)。它在索引 1 处找不到 @
,因此 .*?
匹配 a
字符。此 .*?
模式 扩展 的次数与 @
以外的字符一样多,直到第一个 @
.
参见lazy dot matching based pattern demo here,这里是匹配步骤:
如果可能的话,否定字符 类 通常应该优先于惰性匹配。
如果正则表达式成功,^@[^@]*@
可以一步匹配@
之间的内容,而^@.*?@
需要对@
之间的每个字符展开s.
当失败时(对于没有结尾 @
的情况)大多数正则表达式引擎会应用一点魔法并在内部将 [^@]*
视为 [^@]*+
,因为有一个清晰的边界在 @
和非 @
之间,因此它将匹配到字符串的末尾,识别丢失的 @
并且不回溯,但立即失败。 .*?
将照常扩展一个字符一个字符。
在较大的上下文中使用时,[^@]*
也永远不会扩展到结尾 @
的边界,而这对于惰性匹配来说是很有可能的。例如。 ^@[^@]*a[^@]*@
不会匹配 @bbbb@a@
而 ^@.*?a.*?@
会。
请注意,[^@]
也将匹配换行符,而 .
则不会(在大多数正则表达式引擎中,除非在单行模式下使用)。您可以通过将换行符添加到否定中来避免这种情况 - 如果不需要的话。
我需要从字符串 @anything_here@dhhhd@shdjhjs@
中匹配 @anything_here@
。所以我使用了以下正则表达式。
^@.*?@
或
^@[^@]*@
两种方法都行,但我想知道哪种方法更好。具有非贪婪重复的正则表达式或具有否定字符的正则表达式 class?
显然 ^@[^@]*@
选项要好得多。
否定字符 class 被量化 greedily 这意味着正则表达式引擎会立即抓取除 @
之外的 0 个或更多字符,尽可能多.参见 this regex demo 并匹配:
当您使用惰性点匹配模式时,引擎会匹配 @
,然后尝试匹配结尾的 @
(跳过 .*?
)。它在索引 1 处找不到 @
,因此 .*?
匹配 a
字符。此 .*?
模式 扩展 的次数与 @
以外的字符一样多,直到第一个 @
.
参见lazy dot matching based pattern demo here,这里是匹配步骤:
如果可能的话,否定字符 类 通常应该优先于惰性匹配。
如果正则表达式成功,^@[^@]*@
可以一步匹配@
之间的内容,而^@.*?@
需要对@
之间的每个字符展开s.
当失败时(对于没有结尾 @
的情况)大多数正则表达式引擎会应用一点魔法并在内部将 [^@]*
视为 [^@]*+
,因为有一个清晰的边界在 @
和非 @
之间,因此它将匹配到字符串的末尾,识别丢失的 @
并且不回溯,但立即失败。 .*?
将照常扩展一个字符一个字符。
在较大的上下文中使用时,[^@]*
也永远不会扩展到结尾 @
的边界,而这对于惰性匹配来说是很有可能的。例如。 ^@[^@]*a[^@]*@
不会匹配 @bbbb@a@
而 ^@.*?a.*?@
会。
请注意,[^@]
也将匹配换行符,而 .
则不会(在大多数正则表达式引擎中,除非在单行模式下使用)。您可以通过将换行符添加到否定中来避免这种情况 - 如果不需要的话。