kna*_*ser 4121 regex regex-negation
我知道可以匹配一个单词,然后使用其他工具(例如grep -v
)反转匹配.但是,我想知道是否可以使用正则表达式匹配不包含特定单词的行(例如hede).
输入:
hoho
hihi
haha
hede
Run Code Online (Sandbox Code Playgroud)
码:
grep "<Regex for 'doesn't contain hede'>" input
Run Code Online (Sandbox Code Playgroud)
期望的输出:
hoho
hihi
haha
Run Code Online (Sandbox Code Playgroud)
Bar*_*ers 5622
正则表达式不支持逆匹配的概念并不完全正确.您可以使用负面外观来模仿此行为:
^((?!hede).)*$
Run Code Online (Sandbox Code Playgroud)
上面的正则表达式将匹配任何字符串,或没有换行符的行,不包含(子)字符串'hede'.如上所述,这不是正则表达式(或应该做的)"好"的东西,但仍然是可能的.
如果您还需要匹配换行符,请使用DOT-ALL修饰符(s
以下模式中的尾部):
/^((?!hede).)*$/s
Run Code Online (Sandbox Code Playgroud)
或者内联使用:
/(?s)^((?!hede).)*$/
Run Code Online (Sandbox Code Playgroud)
(/.../
正则表达式是正则表达式分隔符,即不是模式的一部分)
如果DOT-ALL修饰符不可用,则可以使用字符类模仿相同的行为[\s\S]
:
/^((?!hede)[\s\S])*$/
Run Code Online (Sandbox Code Playgroud)
字符串只是一个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
Run Code Online (Sandbox Code Playgroud)
其中e
的是空字符串.正则表达式(?!hede).
向前看是否没有要查看的子字符串"hede"
,如果是这种情况(所以看到别的东西),那么.
(点)将匹配除换行符之外的任何字符.环视也称为零宽度断言,因为它们不消耗任何字符.他们只断言/验证某些东西.
因此,在我的示例中,首先验证每个空字符串,以查看"hede"
在.
(点)消耗字符之前是否没有提前.正则表达式(?!hede).
只会执行一次,所以它被包装在一个组中,并重复零次或多次:((?!hede).)*
.最后,锚定输入的开始和结束以确保消耗整个输入:^((?!hede).)*$
正如你所看到的,输入"ABhedeCD"
将失败,因为上e3
,正则表达式(?!hede)
失败(也就是 "hede"
向上前进!).
Jos*_*vid 710
请注意,解决方案不以 "hede" 开头:
^(?!hede).*$
Run Code Online (Sandbox Code Playgroud)
通常比不包含 "hede"的解决方案更有效:
^((?!hede).)*$
Run Code Online (Sandbox Code Playgroud)
前者仅在输入字符串的第一个位置而不是在每个位置检查"hede".
Ath*_*ena 199
如果您只是将它用于grep,则可以使用grep -v hede
获取所有不包含hede的行.
ETA哦,重读这个问题,grep -v
可能就是你所说的"工具选项".
Jes*_*ica 150
回答:
^((?!hede).)*$
Run Code Online (Sandbox Code Playgroud)
说明:
^
字符串的开头,
(
组和捕获到\ 1(0次或更多次(匹配尽可能多的数量)),
(?!
展望未来,看看是否有,
hede
你的字符串,
)
结束前瞻,
.
除了\n之外的任何字符
)*
,\ 1结束(注意:因为你在这个捕获中使用量词,只有最后重复捕获的模式将存储在\ 1中)
$
才能选择\n,和字符串的结尾
Had*_*s32 98
给出的答案非常好,只是一个学术观点:
理论计算机科学意义上的正则表达式不是这样做的.对他们来说,它必须看起来像这样:
^([^h].*$)|(h([^e].*$|$))|(he([^h].*$|$))|(heh([^e].*$|$))|(hehe.+$)
Run Code Online (Sandbox Code Playgroud)
这只是完全匹配.为子匹配做这件事甚至会更加尴尬.
Roy*_*ker 57
如果您希望正则表达式测试仅在整个字符串匹配时失败,则以下内容将起作用:
^(?!hede$).*
Run Code Online (Sandbox Code Playgroud)
例如 - 如果你想允许除"foo"之外的所有值(即"foofoo","barfoo"和"foobar"将通过,但"foo"将失败),请使用: ^(?!foo$).*
当然,如果你正在检查确切的相等性,那么在这种情况下更好的通用解决方案是检查字符串是否相等,即
myStr !== 'foo'
Run Code Online (Sandbox Code Playgroud)
如果您需要任何正则表达式功能(这里是不区分大小写和范围匹配),您甚至可以将否定置于测试之外:
!/^[a-f]oo$/i.test(myStr)
Run Code Online (Sandbox Code Playgroud)
然而,在需要正面的正则表达式测试的情况下(可能通过API),此答案顶部的正则表达式解决方案可能会有所帮助.
aki*_*kim 53
FWIW,因为常规语言(也称为理性语言)在互补下被关闭,所以总是可以找到否定另一个表达式的正则表达式(也称为理性表达式).但实现这一点的工具并不多.
Vcsn支持此运算符(它表示{c}
后缀).
标签信(:你先定义表达式的类型lal_char
),从挑选a
到z
(与互补工作时定义的字母,当然是非常重要的),例如,与"价值"计算每个字仅仅是一个布尔:true
这个词被接受了false
,被拒绝了.
在Python中:
In [5]: import vcsn
c = vcsn.context('lal_char(a-z), b')
c
Out[5]: {a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z} ?
Run Code Online (Sandbox Code Playgroud)
然后输入你的表达式:
In [6]: e = c.expression('(hede){c}'); e
Out[6]: (hede)^c
Run Code Online (Sandbox Code Playgroud)
将此表达式转换为自动机:
In [7]: a = e.automaton(); a
Run Code Online (Sandbox Code Playgroud)
最后,将此自动机转换回简单表达式.
In [8]: print(a.expression())
\e+h(\e+e(\e+d))+([^h]+h([^e]+e([^d]+d([^e]+e[^]))))[^]*
Run Code Online (Sandbox Code Playgroud)
其中+
通常被表示|
,\e
表示空字,并且[^]
通常被写成.
(任何字符).所以,稍微重写一下()|h(ed?)?|([^h]|h([^e]|e([^d]|d([^e]|e.)))).*
.
amo*_*biz 43
使用负向前瞻,正则表达式可以匹配不包含特定模式的内容.Bart Kiers回答并解释了这一点.很棒的解释!
但是,根据Bart Kiers的回答,前瞻部分将在匹配任何单个字符时测试前方1到4个字符.我们可以避免这种情况,让前瞻部分检查整个文本,确保没有'hede',然后正常部分(.*)可以一次吃掉整个文本.
这是改进的正则表达式:
/^(?!.*?hede).*$/
Run Code Online (Sandbox Code Playgroud)
注意负前瞻部分中的(*?)惰性量词是可选的,你可以使用(*)贪心量词,取决于你的数据:如果'hede'确实存在,并且在文本的开头一半,懒惰量词可以更快; 否则,贪婪量词会更快.但是,如果'hede'不存在,两者都会相等.
这是演示代码.
有关前瞻的更多信息,请查看精彩的文章:掌握Lookahead和Lookbehind.
另外,请查看RegexGen.js,这是一个JavaScript正则表达式生成器,可帮助构建复杂的正则表达式.使用RegexGen.js,您可以以更易读的方式构造正则表达式:
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()
);
Run Code Online (Sandbox Code Playgroud)
Fal*_*lco 41
我决定评估一些呈现的选项并比较它们的性能,以及使用一些新功能..NET Regex引擎的基准测试:http://regexhero.net/tester/
前7行不匹配,因为它们包含搜索的表达式,而较低的7行应该匹配!
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.
Run Code Online (Sandbox Code Playgroud)
结果是每秒迭代次数为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
Run Code Online (Sandbox Code Playgroud)
由于.NET不支持动作动词(*FAIL等),我无法测试解决方案P1和P2.
我试图测试大多数提议的解决方案,某些优化可能对某些单词有效.例如,如果搜索字符串的前两个字母不相同,则可以扩展答案03以
^(?>[^R]+|R+(?!egex Hero))*$
获得较小的性能增益.
但总体上最具可读性和性能最快的解决方案似乎是05使用条件语句或04使用积极量词.我认为Perl解决方案应该更快,更容易阅读.
小智 32
不是正则表达式,但我发现使用带管道的串行greps来消除噪音是合乎逻辑且有用的.
例如.在没有所有评论的情况下搜索apache配置文件 -
grep -v '\#' /opt/lampp/etc/httpd.conf # this gives all the non-comment lines
Run Code Online (Sandbox Code Playgroud)
和
grep -v '\#' /opt/lampp/etc/httpd.conf | grep -i dir
Run Code Online (Sandbox Code Playgroud)
串行grep的逻辑是(不是注释)和(匹配dir)
Cas*_*yte 29
有了这个,你就可以避免在每个位置测试前瞻:
/^(?:[^h]+|h++(?!ede))*+$/
Run Code Online (Sandbox Code Playgroud)
相当于(for .net):
^(?>(?:[^h]+|h+(?!ede))*)$
Run Code Online (Sandbox Code Playgroud)
老答案:
/^(?>[^h]+|h+(?!ede))*$/
Run Code Online (Sandbox Code Playgroud)
ike*_*ami 21
前面提到(?:(?!hede).)*
的很好,因为它可以锚定.
^(?:(?!hede).)*$ # A line without hede
foo(?:(?!hede).)*bar # foo followed by bar, without hede between them
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,以下就足够了:
^(?!.*hede) # A line without hede
Run Code Online (Sandbox Code Playgroud)
这种简化已准备好添加"AND"子句:
^(?!.*hede)(?=.*foo)(?=.*bar) # A line with foo and bar, but without hede
^(?!.*hede)(?=.*foo).*bar # Same
Run Code Online (Sandbox Code Playgroud)
rid*_*ner 19
这是我如何做到的:
^[^h]*(h(?!ede)[^h]*)*$
Run Code Online (Sandbox Code Playgroud)
比其他答案准确而有效.它实现了Friedl的"展开循环"效率技术,并且需要更少的回溯.
diy*_*ism 17
如果你想匹配一个字符来否定一个类似于否定字符类的单词:
例如,一个字符串:
<?
$str="aaa bbb4 aaa bbb7";
?>
Run Code Online (Sandbox Code Playgroud)
不使用:
<?
preg_match('/aaa[^bbb]+?bbb7/s', $str, $matches);
?>
Run Code Online (Sandbox Code Playgroud)
使用:
<?
preg_match('/aaa(?:(?!bbb).)+?bbb7/s', $str, $matches);
?>
Run Code Online (Sandbox Code Playgroud)
注意"(?!bbb)."
既不是lookbehind也不是lookahead,它是lookcurrent,例如:
"(?=abc)abcde", "(?!abc)abcde"
Run Code Online (Sandbox Code Playgroud)
sta*_*afl 14
在我看来,最佳答案的可读性更高:
^(?!.*hede)
Run Code Online (Sandbox Code Playgroud)
基本上,“仅当行中没有'hede'时,才在行的开头进行匹配”-因此,要求几乎直接转换为regex。
当然,可能有多种故障要求:
^(?!.*(hede|hodo|hada))
Run Code Online (Sandbox Code Playgroud)
详细信息: ^锚确保正则表达式引擎不会在字符串的每个位置(将匹配每个字符串)重试匹配项。
开头的^锚点代表行的开头。grep工具一次匹配每一行,在使用多行字符串的情况下,可以使用“ m”标志:
/^(?!.*hede)/m # JavaScript syntax
Run Code Online (Sandbox Code Playgroud)
要么
(?m)^(?!.*hede) # Inline flag
Run Code Online (Sandbox Code Playgroud)
Emm*_*mma 14
另一种选择是添加一个积极的前瞻并检查hede
输入行中的任何位置,然后我们将否定它,使用类似于以下的表达式:
^(?!(?=.*\bhede\b)).*$
Run Code Online (Sandbox Code Playgroud)
与字边界。
该表达式在regex101.com 的右上角面板中进行了解释,如果您希望探索/简化/修改它,并且在此链接中,您可以观看它如何与某些示例输入匹配,如果您愿意的话。
jex.im可视化正则表达式:
Kev*_*gan 13
OP未指定或Tag指示正在使用Regex的上下文(编程语言,编辑器,工具)的帖子.
对我来说,我有时需要在使用时编辑文件时这样做Textpad
.
Textpad
支持一些正则表达式,但不支持前瞻或后瞻,所以它需要几个步骤.
如果我想保留所有不包含字符串的行hede
,我会这样做:
1.搜索/替换整个文件,以在包含任何文本的每行的开头添加唯一的"标记".
Search string:^(.)
Replace string:<@#-unique-#@>\1
Replace-all
Run Code Online (Sandbox Code Playgroud)
2.删除包含该字符串的所有行
hede
(替换字符串为空):
Search string:<@#-unique-#@>.*hede.*\n
Replace string:<nothing>
Replace-all
Run Code Online (Sandbox Code Playgroud)
3.此时,所有剩余的行都不包含字符串
hede
.从所有行中删除唯一的"Tag"(替换字符串为空):
Search string:<@#-unique-#@>
Replace string:<nothing>
Replace-all
Run Code Online (Sandbox Code Playgroud)
现在您有原始文本,其中所有行都包含hede
删除的字符串.
如果我正在寻找Do Something Else只有不包含字符串的行hede
,我会这样做:
1.搜索/替换整个文件,以在包含任何文本的每行的开头添加唯一的"标记".
Search string:^(.)
Replace string:<@#-unique-#@>\1
Replace-all
Run Code Online (Sandbox Code Playgroud)
2.对于包含该字符串的所有行
hede
,删除唯一的"Tag":
Search string:<@#-unique-#@>(.*hede)
Replace string:\1
Replace-all
Run Code Online (Sandbox Code Playgroud)
3.此时,所有以唯一"标记"开头的行都不包含字符串
hede
.我现在可以做我的其他东西了.
4.完成后,我从所有行中删除唯一的"Tag"(替换字符串为空):
Search string:<@#-unique-#@>
Replace string:<nothing>
Replace-all
Run Code Online (Sandbox Code Playgroud)
ael*_*lor 11
自从引入ruby-2.4.1以来,我们可以在Ruby的正则表达式中使用新的Absent Operator
来自官方文件
(?~abc) matches: "", "ab", "aab", "cccc", etc.
It doesn't match: "abc", "aabc", "ccccabc", etc.
Run Code Online (Sandbox Code Playgroud)
因此,在您的情况下,为您^(?~hede)$
完成工作
2.4.1 :016 > ["hoho", "hihi", "haha", "hede"].select{|s| /^(?~hede)$/.match(s)}
=> ["hoho", "hihi", "haha"]
Run Code Online (Sandbox Code Playgroud)
通过PCRE动词 (*SKIP)(*F)
^hede$(*SKIP)(*F)|^.*$
Run Code Online (Sandbox Code Playgroud)
这将完全跳过包含确切字符串的行hede
并匹配所有剩余行.
执行部件:
让我们通过将它分成两部分来考虑上面的正则表达式.
|
符号前面的部分.部分不应该匹配.
^hede$(*SKIP)(*F)
Run Code Online (Sandbox Code Playgroud)|
符号之后的部分.部分应该匹配.
^.*$
Run Code Online (Sandbox Code Playgroud)第1部分
正则表达式引擎将从第一部分开始执行.
^hede$(*SKIP)(*F)
Run Code Online (Sandbox Code Playgroud)
说明:
^
断言我们刚开始.hede
匹配字符串 hede
$
断言我们在线端.所以包含字符串的hede
行将匹配.一旦正则表达式引擎看到以下内容(*SKIP)(*F)
(注意:您可以写(*F)
为(*FAIL)
)动词,它会跳过并使匹配失败.|
在PCRE动词旁边添加了一个名为alteration或逻辑OR运算符,它匹配所有行中每个字符之间的所有边界,除了该行包含精确的字符串hede
.请在此处查看演示.也就是说,它尝试匹配剩余字符串中的字符.现在第二部分的正则表达式将被执行.
第2部分
^.*$
Run Code Online (Sandbox Code Playgroud)
说明:
^
断言我们刚开始.即,它匹配除hede
行中的那一行之外的所有行开始.请在此处查看演示..*
在多行模式下,.
将匹配除换行符或回车符之外的任何字符.并且*
会重复前一个字符零次或多次.所以.*
会匹配整条线.请在此处查看演示.
嘿,为什么你添加.*而不是.+?
因为.*
匹配空行但.+
不匹配空白.我们希望匹配所有行,除了hede
输入中可能还有空行.所以你必须使用.*
而不是.+
..+
将重复前一个字符一次或多次.请参阅此处.*
匹配空白行.
$
这里不需要行锚的结束.
由于没有其他人直接回答被问到的问题,我会这样做.
答案是,使用POSIX grep
,不可能真正满足这个要求:
grep "<Regex for 'doesn't contain hede'>" input
Run Code Online (Sandbox Code Playgroud)
原因是POSIX grep
只需要使用Basic Regular Expressions,它根本不足以完成该任务(由于缺少交替和分组,它们无法解析常规语言).
但是,GNU grep
实现了允许它的扩展.特别\|
是GNU实现BRE的交替运算符,\(
并且\)
是分组运算符.如果你的正则表达式引擎支持交替,负括号表达式,分组和Kleene星,并且能够锚定到字符串的开头和结尾,这就是这种方法所需要的.
使用GNU [^ ... ]
,它将是这样的:
grep "^\([^h]\|h\(h\|eh\|edh\)*\([^eh]\|e[^dh]\|ed[^eh]\)\)*\(\|h\(h\|eh\|edh\)*\(\|e\|ed\)\)$" input
Run Code Online (Sandbox Code Playgroud)
(与Grail和手工制作的一些进一步优化相结合).
您还可以使用实现扩展正则表达式的工具,例如(a|b|c| ... )
,去掉反斜杠:
egrep "^([^h]|h(h|eh|edh)*([^eh]|e[^dh]|ed[^eh]))*(|h(h|eh|edh)*(|e|ed))$" input
Run Code Online (Sandbox Code Playgroud)
这是一个测试它的脚本(注意它grep
在当前目录中生成一个文件):
#!/bin/bash
REGEX="^\([^h]\|h\(h\|eh\|edh\)*\([^eh]\|e[^dh]\|ed[^eh]\)\)*\(\|h\(h\|eh\|edh\)*\(\|e\|ed\)\)$"
# First four lines as in OP's testcase.
cat > testinput.txt <<EOF
hoho
hihi
haha
hede
h
he
ah
head
ahead
ahed
aheda
ahede
hhede
hehede
hedhede
hehehehehehedehehe
hedecidedthat
EOF
diff -s -u <(grep -v hede testinput.txt) <(grep "$REGEX" testinput.txt)
Run Code Online (Sandbox Code Playgroud)
在我的系统中打印:
Files /dev/fd/63 and /dev/fd/62 are identical
Run Code Online (Sandbox Code Playgroud)
正如所料.
对于那些对细节感兴趣的人,采用的技术是将匹配单词的正则表达式转换为有限自动机,然后通过将每个接受状态更改为不接受而反之亦然,反之亦然,然后将生成的FA转换回一个正则表达式.
最后,正如每个人都注意到的,如果你的正则表达式引擎支持负向前瞻,那么这会简化任务.例如,使用GNU grep:
grep -P '^((?!hede).)*$' input
Run Code Online (Sandbox Code Playgroud)
更新:我最近发现了Kendall Hopkins的优秀FormalTheory库,用PHP编写,提供类似于Grail的功能.使用它,以及我自己编写的简化器,我已经能够编写一个带有输入短语的负正则表达式的在线生成器(目前只支持字母数字和空格字符):http://www.formauri.es/personal/ pgimeno /杂项/不匹配正则表达式/
对于egrep
它输出:
^([^h]|h(h|e(h|dh))*([^eh]|e([^dh]|d[^eh])))*(h(h|e(h|dh))*(ed?)?)?$
Run Code Online (Sandbox Code Playgroud)
这相当于上述.
代码中的两个正则表达式可能更易于维护,一个用于执行第一个匹配,然后如果匹配则运行第二个正则表达式以检查您希望阻止的异常情况,例如^.*(hede).*
在代码中具有适当的逻辑.
好的,我承认这不是对发布的问题的真正答案,它也可能比单个正则表达式使用稍多的处理.但对于那些来到这里寻找快速紧急修复异常情况的开发人员来说,这个解决方案不应该被忽视.
如果您尝试匹配包含字符串X但不包含字符串Y的整行,我想添加另一个示例。
例如,假设我们要检查 URL/字符串是否包含“ tasty-treats ”,只要它不包含“ chocolate ”即可。
这个正则表达式模式可以工作(也可以在 JavaScript 中工作)
^(?=.*?tasty-treats)((?!chocolate).)*$
Run Code Online (Sandbox Code Playgroud)
(示例中是全局多行标志)
交互示例: https: //regexr.com/53gv4
(这些网址包含“美味佳肴”,也不包含“巧克力”)
(这些网址在某处包含“巧克力” - 因此即使它们包含“美味佳肴”,它们也不会匹配)
只要您正在处理线条,只需标记负面匹配并瞄准其余的即可。
事实上,我在 sed 中使用这个技巧,因为^((?!hede).)*$
它看起来不支持。
标记否定匹配:(例如带有 的行hede
),使用根本不包含在整个文本中的字符。为此,表情符号可能是一个不错的选择。
s/(.*hede)/\1/g
Run Code Online (Sandbox Code Playgroud)瞄准其余部分(未标记的字符串:例如没有 的行hede
)。假设您只想保留目标并删除其余的(根据您的需要):
s/^.*//g
Run Code Online (Sandbox Code Playgroud)假设您要删除目标:
标记否定匹配:(例如带有 的行hede
),使用根本不包含在整个文本中的字符。为此,表情符号可能是一个不错的选择。
s/(.*hede)/\1/g
Run Code Online (Sandbox Code Playgroud)瞄准其余部分(未标记的字符串:例如没有 的行hede
)。假设您要删除目标:
s/^[^].*//g
Run Code Online (Sandbox Code Playgroud)去掉标记:
s///g
Run Code Online (Sandbox Code Playgroud)该TXR语言支持正则表达式的否定.
$ txr -c '@(repeat)
@{nothede /~hede/}
@(do (put-line nothede))
@(end)' Input
Run Code Online (Sandbox Code Playgroud)
一个更复杂的示例:匹配以_开头a
和结尾的所有行z
,但不包含子字符串hede
:
$ txr -c '@(repeat)
@{nothede /a.*z&~.*hede.*/}
@(do (put-line nothede))
@(end)' -
az <- echoed
az
abcz <- echoed
abcz
abhederz <- not echoed; contains hede
ahedez <- not echoed; contains hede
ace <- not echoed; does not end in z
ahedz <- echoed
ahedz
Run Code Online (Sandbox Code Playgroud)
正则表达式否定本身并不特别有用,但是当你也有交集时,事情变得有趣,因为你有一套完整的布尔集操作:你可以表达"匹配这个的集合,除了与之匹配的东西".
以下功能将帮助您获得所需的输出
<?PHP
function removePrepositions($text){
$propositions=array('/\bfor\b/i','/\bthe\b/i');
if( count($propositions) > 0 ) {
foreach($propositions as $exceptionPhrase) {
$text = preg_replace($exceptionPhrase, '', trim($text));
}
$retval = trim($text);
}
return $retval;
}
?>
Run Code Online (Sandbox Code Playgroud)
小智 5
^((?!hede).)*$
是一个优雅的解决方案,除了它消耗字符之外,您将无法将其与其他条件结合起来。例如,假设您想检查是否存在“hede”和是否存在“haha”。该解决方案可行,因为它不会消耗字符:
^(?!.*\bhede\b)(?=.*\bhaha\b)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3155992 次 |
最近记录: |