Regex 正则表达式以查找正匹配和负匹配
我希望在regex(TCL)中匹配正负字符的组合 假设我想匹配包含'def'和不包含'hij'的行Regex 正则表达式以查找正匹配和负匹配,regex,tcl,Regex,Tcl,我希望在regex(TCL)中匹配正负字符的组合 假设我想匹配包含'def'和不包含'hij'的行 ab def hhh -> print abdefxxhijzz -> no print hij -> no print 123defhijxyz -> no print 0def123hijxyz -> no print 我试过: {(def)(?!hij)} {(def).*(?!hij)} {.*(def).*(?!hij)} {
ab def hhh -> print
abdefxxhijzz -> no print
hij -> no print
123defhijxyz -> no print
0def123hijxyz -> no print
我试过:
{(def)(?!hij)}
{(def).*(?!hij)}
{.*(def).*(?!hij)}
{.*(def).*(?!hij).*}
全部错误地打印“0def123hijxyz”
在命令行中,我可以使用2个grep命令行来执行此操作
echo 0def123hijxyz | grep def | grep -v hij
你们中的一位专家能否帮助使用regexp来实现这一目标
谢谢,
Gert.此正则表达式应适用于:
(?!.*hij)(.*def.*)
它向前查找子字符串
*hij
,如果找不到,它将匹配(*def.*)
此正则表达式应该可以工作:
(?!.*hij)(.*def.*)
它将查找子字符串
*hij
,如果找不到,它将匹配(.*def.*)
我将此视为两个任务,而我根本看不到需要的正则表达式
首先搜索包含所需字符串(“def”)的字符串,然后仅当该字符串通过第一次测试时,验证它不包含禁止字符串(“hij”)
根据哪一个更有可能消除最多的可能性,将此作为第一步。例如,如果更多的字符串更可能包含禁止的字符串,请首先进行该检查,因为您的代码将更高效。我将此视为两项任务,而我根本不认为需要正则表达式 首先搜索包含所需字符串(“def”)的字符串,然后仅当该字符串通过第一次测试时,验证它不包含禁止字符串(“hij”)
根据哪一个更有可能消除最多的可能性,将此作为第一步。例如,如果更多的字符串更可能包含禁止的字符串,请首先执行该检查,因为您的代码将更高效。您已经接近,但您需要首先执行负前瞻,并锚定它,以确保只在字符串开头应用一次
{(?n)^(?!.*hij).*def.*}
打开(?n)
模式,允许-line
在行首匹配(大多数正则表达式称之为^
模式)多行
在整个字符串中搜索(?!*hij)
,如果找到,则报告失败hij
如果包含*def.
,则使用整个字符串def
% check {^(?!.*hij.*$).*def}
ab def hhh => 1
abdefxxhijzz => 0
hij => 0
123defhijxyz => 0
0def123hijxyz => 0
锚定是必要的,以防止它匹配一个字符串,其中不需要的单词位于想要的单词之前,如
hij def
。如果没有锚定,它可以通过从i
开始查找匹配项。您已经很接近了,但是您需要首先执行负前瞻,并锚定它,以确保只在字符串开头应用一次
{(?n)^(?!.*hij).*def.*}
打开(?n)
模式,允许-line
在行首匹配(大多数正则表达式称之为^
模式)多行
在整个字符串中搜索(?!*hij)
,如果找到,则报告失败hij
如果包含*def.
,则使用整个字符串def
% check {^(?!.*hij.*$).*def}
ab def hhh => 1
abdefxxhijzz => 0
hij => 0
123defhijxyz => 0
0def123hijxyz => 0
锚定是必要的,以防止它匹配一个字符串,其中不需要的单词位于想要的单词之前,如
hij def
。如果没有锚,它可以从i
开始查找匹配项。对于这种检查,我宁愿不使用regexp,而使用字符串方法:
if {[string match *def* "0def123hijxyz"] && ![string match *hij* "0def123hijxyz"]} {
puts "Match!"
}
字符串匹配
使用全局匹配,因此*
是通配符
[string match*def*“0def123hijxyz”]
如果def
在字符串中,则返回1,否则返回0
如果您仍然坚持使用regexp方法,我建议使用以下regex:
^(?!.*hij).*def
^
是行锚的开始,它使regexp仅检查一次匹配,而不是在匹配失败时重复检查匹配(即,在发现存在hij
或没有def
之后)
在(?!.*hij)
中添加*
可以检查整个字符串,而不是字符串中的单个位置
{(?n)^(?!.*hij).*def.*}
*def
然后尝试匹配def
。您不必在结尾使用另一个*
字符,除非有更多字符需要匹配,例如,def
后跟g
,即使中间有其他字符将是*def..g
。最后使用这个*
只会给regexp带来更多的工作
一些基准测试
% proc match {} {
if {[string match *def* "0def123hijxyz"] && ![string match *hij* "0def12
3hijxyz"]} {
}
}
% proc regmatch {} {
if {[regexp -- {^(?!.*hij).*def} 0def123hijxyz]} {
}
}
% puts [time match 100000]
0.49533 microseconds per iteration
% puts [time regmatch 100000]
1.38854 microseconds per iteration
% proc regmatcher {} {
if {[regexp -- {(?n)^(?!.*hij).*def.*} 0def123hijxyz]} {
}
}
% puts [time regmatcher 100000]
2.23913 microseconds per iteration
regexp
比简单字符串方法花费的时间长2-4倍。对于这种检查,我宁愿不使用regexp,而使用字符串方法:
if {[string match *def* "0def123hijxyz"] && ![string match *hij* "0def123hijxyz"]} {
puts "Match!"
}
字符串匹配
使用全局匹配,因此*
是通配符
[string match*def*“0def123hijxyz”]
如果def
在字符串中,则返回1,否则返回0
如果您仍然坚持使用regexp方法,我建议使用以下regex:
^(?!.*hij).*def
^
是行锚的开始,它使regexp仅检查一次匹配,而不是在匹配失败时重复检查匹配(即,在发现存在hij
或没有def
之后)
在(?!.*hij)
中添加*
可以检查整个字符串,而不是字符串中的单个位置
{(?n)^(?!.*hij).*def.*}
*def
然后尝试匹配def
。您不必在结尾使用另一个*
字符,除非有更多字符需要匹配,例如,def
后跟g
,即使中间有其他字符将是*def..g
。最后使用这个*
只会给regexp带来更多的工作
一些基准测试
% proc match {} {
if {[string match *def* "0def123hijxyz"] && ![string match *hij* "0def12
3hijxyz"]} {
}
}
% proc regmatch {} {
if {[regexp -- {^(?!.*hij).*def} 0def123hijxyz]} {
}
}
% puts [time match 100000]
0.49533 microseconds per iteration
% puts [time regmatch 100000]
1.38854 microseconds per iteration
% proc regmatcher {} {
if {[regexp -- {(?n)^(?!.*hij).*def.*} 0def123hijxyz]} {
}
}
% puts [time regmatcher 100000]
2.23913 microseconds per iteration
regexp
比简单字符串方法花费的时间长2-4倍。在测试这类东西时,制作一个小测试程序有助于:
proc check {re} {
foreach s {"ab def hhh" "abdefxxhijzz" "hij" "123defhijxyz" "0def123hijxyz"} {
puts "$s => [regexp $re $s]"
}
}
让我们看看……