字符串只是一个 n 人物。每个字符前后都有一个空字符串。那么一份 n 角色将具有 n+1 空字符串。考虑字符串 "ABhedeCD" :
┌──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┐
S = │e1│ A │e2│ B │e3│ h │e4│ e │e5│ d │e6│ e │e7│ C │e8│ D │e9│
└──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┘
index 0 1 2 3 4 5 6 7
var _ = regexGen;
var regex = _(
_.startOfLine(),
_.anything().notContains( // match anything that not contains:
_.anything().lazy(), 'hede' // zero or more chars that followed by 'hede',
// i.e., anything contains 'hede'
),
_.endOfLine()
);
Regex Hero is a real-time online Silverlight Regular Expression Tester.
XRegex Hero is a real-time online Silverlight Regular Expression Tester.
Regex HeroRegex HeroRegex HeroRegex HeroRegex Hero is a real-time online Silverlight Regular Expression Tester.
Regex Her Regex Her Regex Her Regex Her Regex Her Regex Her Regex Hero is a real-time online Silverlight Regular Expression Tester.
Regex Her is a real-time online Silverlight Regular Expression Tester.Regex Hero
egex Hero egex Hero egex Hero egex Hero egex Hero egex Hero Regex Hero is a real-time online Silverlight Regular Expression Tester.
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRegex Hero is a real-time online Silverlight Regular Expression Tester.
Regex Her
egex Hero
egex Hero is a real-time online Silverlight Regular Expression Tester.
Regex Her is a real-time online Silverlight Regular Expression Tester.
Regex Her Regex Her Regex Her Regex Her Regex Her Regex Her is a real-time online Silverlight Regular Expression Tester.
Nobody is a real-time online Silverlight Regular Expression Tester.
Regex Her o egex Hero Regex Hero Reg ex Hero is a real-time online Silverlight Regular Expression Tester.
结果:
结果是每秒迭代次数,作为3次运行的中位数-数值越大=越好
01: ^((?!Regex Hero).)*$ 3.914 // Accepted Answer
02: ^(?:(?!Regex Hero).)*$ 5.034 // With Non-Capturing group
03: ^(?>[^R]+|R(?!egex Hero))*$ 6.137 // Lookahead only on the right first letter
04: ^(?>(?:.*?Regex Hero)?)^.*$ 7.426 // Match the word and check if you're still at linestart
05: ^(?(?=.*?Regex Hero)(?#fail)|.*)$ 7.371 // Logic Branch: Find Regex Hero? match nothing, else anything
P1: ^(?(?=.*?Regex Hero)(*FAIL)|(*ACCEPT)) ????? // Logic Branch in Perl - Quick FAIL
P2: .*?Regex Hero(*COMMIT)(*FAIL)|(*ACCEPT) ????? // Direct COMMIT & FAIL in Perl
17条答案
按热度按时间kmb7vmvb1#
regex不支持反向匹配的概念并不完全正确。您可以通过使用负面环视来模拟此行为:
上面的正则表达式将匹配不包含(子)字符串“hede”的任何字符串或不带换行符的行。如前所述,这不是正则表达式“擅长”的(或应该做的),但仍然是可能的。
如果还需要匹配换行符,请使用“点全部”修改器(尾部
s
按照以下模式):或者内联使用:
(凡
/.../
是正则表达式分隔符,即不是模式的一部分)如果“点全部”修改器不可用,则可以模拟角色类的相同行为
[\s\S]
:解释
字符串只是一个
n
人物。每个字符前后都有一个空字符串。那么一份n
角色将具有n+1
空字符串。考虑字符串"ABhedeCD"
:在哪里
e
的是空字符串。正则表达式(?!hede).
向前看,看是否没有子字符串"hede"
被看到,如果是这样的话(看到了其他的东西),那么.
(点)将匹配除换行符以外的任何字符。环视也被称为零宽度Assert,因为它们不使用任何字符。他们只是Assert/验证某些东西。因此,在我的示例中,首先验证每个空字符串,以查看是否没有空字符串
"hede"
向前,在角色被.
(点)。正则表达式(?!hede).
将只执行一次,因此将其 Package 在一个组中,并重复零次或多次:((?!hede).)*
. 最后,锚定输入的开始和结束,以确保使用整个输入:^((?!hede).)*$
如您所见,输入"ABhedeCD"
将失败,因为e3
,正则表达式(?!hede)
失败(有"hede"
在前面!)。h9vpoimq2#
请注意,解决方案并非以“hede”开头:
通常比不包含“hede”的解决方案更有效:
前者只在输入字符串的第一个位置检查“hede”,而不是在每个位置。
alen0pnh3#
如果你只是为了grep使用它,你可以使用
grep -v hede
获取不包含hede的所有行。哦,重读这个问题,
grep -v
可能就是你所说的“工具选项”。fquxozlt4#
答复:
说明:
^
字符串的开头,(
分组并捕获到\1(0次或更多次(匹配尽可能多的数量)),(?!
向前看,看是否有,hede
你的绳子,)
展望未来,.
任何字符,除了\n,)*
结束\1(注意:由于您在此捕获上使用了量词,因此只有捕获模式的最后一次重复将存储在\1中)$
在可选的前\n和字符串的结尾b09cbbtk5#
给出的答案非常好,只是一个学术观点:
理论计算机科学意义上的正则表达式不能这样做。对他们来说,它必须看起来像这样:
这只是一个完整的匹配。在替补比赛中这样做会更加尴尬。
g6ll5ycj6#
如果希望正则表达式测试仅在整个字符串匹配时失败,则以下操作将起作用:
e、 g.--如果要允许除“foo”之外的所有值(即“foofoo”、“barfoo”和“foobar”将通过,但“foo”将失败),请使用:
^(?!foo$).*
当然,如果要检查精确相等性,在这种情况下更好的一般解决方案是检查字符串相等性,即。如果需要任何正则表达式特性(这里是不区分大小写和范围匹配),甚至可以将否定放在测试之外:
但是,在需要进行正则表达式阳性测试(可能是api测试)的情况下,此答案顶部的正则表达式解决方案可能会有所帮助。
pcww981p7#
fwiw,因为正则语言(也称为rational语言)在互补下是封闭的,所以总是可以找到一个否定另一个表达式的正则表达式(称为rational表达式)。但实现这一点的工具并不多。
vcsn支持此运算符(它表示
{c}
,后缀)。首先定义表达式的类型:标签是字母(
lal_char
)取材a
到z
例如(在使用补语时定义字母表当然非常重要),为每个单词计算的“值”只是一个布尔值:true
这个词被接受了,false
,被拒绝。在python中:
然后输入表达式:
将此表达式转换为自动机:
最后,将此自动机转换回简单表达式。
哪里
+
通常表示为|
,\e
表示空单词,并且[^]
通常是书面的.
(任何字符)。所以,经过一点改写()|h(ed?)?|([^h]|h([^e]|e([^d]|d([^e]|e.)))).*
.您可以在这里看到这个示例,并在那里在线尝试vcsn。
8wigbo568#
这里有一个很好的解释,解释为什么否定任意正则表达式并不容易。不过,我必须同意其他答案:如果这不是一个假设问题,那么正则表达式在这里不是正确的选择。
wbgh16ku9#
使用负前瞻,正则表达式可以匹配不包含特定模式的内容。巴特·基尔斯对此进行了回答和解释。很好的解释!
然而,根据巴特·基尔斯的回答,前瞻部分将在匹配任何单个字符时测试1到4个字符。我们可以避免这种情况,让先行部分检查整个文本,确保没有“hede”,然后正常部分(*)可以一次吃掉整个文本。
以下是改进的正则表达式:
请注意,负前瞻部分中的(?)惰性量词是可选的,您可以使用()贪婪量词,具体取决于您的数据:如果“hede”确实存在,并且在文本的前半部分,惰性量词可以更快;否则,贪婪的量词会更快。但是,如果“hede”不存在,则两者的速度将相等。
这是演示代码。
有关前瞻的更多信息,请查看这篇伟大的文章:掌握前瞻和落后。
另外,请查看regexgen.js,它是一个javascript正则表达式生成器,有助于构造复杂的正则表达式。使用regexgen.js,您可以以更可读的方式构造正则表达式:
b5buobof10#
基准
我决定评估一些提供的选项,比较它们的性能,并使用一些新功能。在.net正则表达式引擎上进行基准测试:http://regexhero.net/tester/
基准文本:
前7行不应该匹配,因为它们包含搜索的表达式,而下7行应该匹配!
结果:
结果是每秒迭代次数,作为3次运行的中位数-数值越大=越好
由于.net不支持动作动词(*fail等),因此我无法测试解决方案p1和p2。
总结:
我试着测试大多数建议的解决方案,对于某些单词,一些优化是可能的。例如,如果搜索字符串的前两个字母不相同,则答案03可以扩展为
^(?>[^R]+|R+(?!egex Hero))*$
从而获得较小的性能增益。但总体而言,可读性和性能方面最快的解决方案似乎是使用条件语句的05或带有所有格量词的04。我认为perl解决方案应该更快,更容易阅读。
mxg2im7a11#
不是正则表达式,但我发现将串行greps与管道一起使用以消除噪声是合乎逻辑且有用的。
搜索一个apache配置文件,不带所有注解-
和
序列grep的逻辑是(不是注解)和(匹配目录)
3xiyfsfu12#
这样,您就可以避免在每个位置上进行前瞻性测试:
相当于(对于.net):
旧答案:
ezykj2lf13#
前述
(?:(?!hede).)*
是伟大的,因为它可以被锚定。但在这种情况下,以下内容就足够了:
这种简化可以添加“和”条款:
hts6caw314#
我是这样做的:
比其他答案更准确、更有效。它实现了friedl的“展开循环”效率技术,并且需要更少的回溯。
68de4m5k15#
在我看来,这是一个更具可读性的顶级答案变体:
基本上,“当且仅当行的开头没有“hede”时才匹配”-因此需求几乎直接转化为正则表达式。
当然,可能有多个故障需求:
详细信息:^锚点确保正则表达式引擎不会在字符串中的每个位置重试匹配,这将匹配每个字符串。
开头的^锚点表示行的开头。grep工具一次匹配一行,在处理多行字符串的上下文中,可以使用“m”标志:
或