我知道可以匹配一个单词然后使用其他工具反转匹配(例如 grep -v
)。但是,我想知道是否可以匹配那些线 别 包含使用正则表达式的特定单词(例如hede)。
输入:
hoho
hihi
haha
hede
码:
grep "<Regex for 'doesn't contain hede'>" input
期望的输出:
hoho
hihi
haha
我知道可以匹配一个单词然后使用其他工具反转匹配(例如 grep -v
)。但是,我想知道是否可以匹配那些线 别 包含使用正则表达式的特定单词(例如hede)。
输入:
hoho
hihi
haha
hede
码:
grep "<Regex for 'doesn't contain hede'>" input
期望的输出:
hoho
hihi
haha
正则表达式不支持逆匹配的概念并不完全正确。您可以使用负面外观来模仿此行为:
^((?!hede).)*$
上面的正则表达式将匹配任何字符串,或没有换行符的行, 不 包含(子)字符串'hede'。如上所述,这不是正则表达式(或应该做的)“好”的东西,但仍然如此 是 可能。
如果你还需要匹配换行符,请使用 DOT-ALL修饰符 (尾随 s
在以下模式中):
/^((?!hede).)*$/s
或者内联使用:
/(?s)^((?!hede).)*$/
(在哪里 /.../
是正则表达式分隔符,即不是模式的一部分)
如果DOT-ALL修饰符不可用,则可以模拟与字符类相同的行为 [\s\S]
:
/^((?!hede)[\s\S])*$/
字符串只是一个列表 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
在哪里 e
是空字符串。正则表达式 (?!hede).
展望未来,看看是否没有子串 "hede"
可以看到,如果是这种情况(所以看到别的东西),那么 .
(点)将匹配除换行符之外的任何字符。环视也被称为 零宽度的断言 因为他们没有 消耗 任何人物。他们只断言/验证某些东西。
因此,在我的示例中,首先验证每个空字符串以查看是否存在 "hede"
在角色消耗之前,向前 .
(点)。正则表达式 (?!hede).
将只执行一次,因此它被包装在一个组中,并重复零次或多次: ((?!hede).)*
。最后,锚定输入的开始和结束以确保消耗整个输入: ^((?!hede).)*$
如您所见,输入 "ABhedeCD"
会因为失败而失败 e3
,正则表达式 (?!hede)
失败(那里 是 "hede"
前方!)。
注意解决方案 才不是 从...开始 “合德”:
^(?!hede).*$
通常比解决方案更有效 才不是 包含 “合德”:
^((?!hede).)*$
前者仅在输入字符串的第一个位置而不是在每个位置检查“hede”。
如果 你只是将它用于grep,你可以使用 grep -v hede
得到所有不包含hede的行。
ETA哦,重读这个问题, grep -v
可能是你所说的“工具选项”。
回答:
^((?!hede).)*$
说明:
^
字符串的开头,
(
分组并捕获到\ 1(0次或更多次(匹配尽可能多的数量)),
(?!
展望未来,看看是否有,
hede
你的字符串,
)
超前结束,
.
除\ n之外的任何字符,
)*
结束\ 1(注意:因为您在此捕获中使用量词,所以只有最后重复捕获的模式将存储在\ 1)
$
在可选的\ n之前,以及字符串的结尾
给出的答案非常好,只是一个学术观点:
正则表达式理论计算机科学的意义 不行 像这样做。对他们来说,它必须看起来像这样:
^([^h].*$)|(h([^e].*$|$))|(he([^h].*$|$))|(heh([^e].*$|$))|(hehe.+$)
这只是一个完全匹配。为子匹配做这件事甚至会更加尴尬。
如果你想要正则表达式测试 只要 如果失败了 整个字符串 匹配,以下将工作:
^(?!hede$).*
例如 - 如果你想允许除“foo”之外的所有值(即“foofoo”,“barfoo”和“foobar”将通过,但“foo”将失败),请使用: ^(?!foo$).*
当然,如果你正在检查 精确 平等,在这种情况下更好的通用解决方案是检查字符串相等,即
myStr !== 'foo'
你甚至可以把这个否定 外 测试是否需要任何正则表达式功能(此处,不区分大小写和范围匹配):
!/^[a-f]oo$/i.test(myStr)
然而,在需要正面正则表达式测试的情况下(可能通过API),顶部的正则表达式解决方案可能会有所帮助。
这里的 一个很好的解释 为什么否定任意正则表达式并不容易。我不得不同意其他答案:如果这不是一个假设的问题,那么正则表达式不是正确的选择。