我有正则表达式的问题。 除了一组指定的单词外,我需要制作正则表达式,例如:apple,orange,juice。 并且给出这些词语,它将匹配除上述词语之外的所有内容。
apple (should not match)
applejuice (match)
yummyjuice (match)
yummy-apple-juice (match)
orangeapplejuice (match)
orange (should not match)
juice (should not match)
orange-apple-juice (match)
apple-orange-aple (match)
juice-juice-juice (match)
orange-juice (match)
答案 0 :(得分:9)
如果你真的想用一个正则表达式来做这件事,你可能会发现外观很有用(在这个例子中尤其是负向前瞻)。为Ruby编写的正则表达式(一些实现具有不同的外观语法):
rx = /^(?!apple$|orange$|juice$)/
答案 1 :(得分:3)
我注意到apple-juice
应根据您的参数匹配,但apple juice
怎么办?我假设如果你要验证apple juice
,你仍然希望它失败。
所以 - 让我们构建一组算作“边界”的字符:
/[^-a-z0-9A-Z_]/ // Will match any character that is <NOT> - _ or
// between a-z 0-9 A-Z
/(?:^|[^-a-z0-9A-Z_])/ // Matches the beginning of the string, or one of those
// non-word characters.
/(?:[^-a-z0-9A-Z_]|$)/ // Matches a non-word or the end of string
/(?:^|[^-a-z0-9A-Z_])(apple|orange|juice)(?:[^-a-z0-9A-Z_]|$)/
// This should >match< apple/orange/juice ONLY when not preceded/followed by another
// 'non-word' character just negate the result of the test to obtain your desired
// result.
在大多数正则表达式中,\b
计为“单词边界”,但“单词字符”的标准列表不包括-
,因此您需要创建自定义单词。如果您还没有尝试抓住/\b(apple|orange|juice)\b/
,它可以与-
匹配...
如果您只是测试“单字”测试,您可以更简单地使用:
/^(apple|orange|juice)$/ // and take the negation of this...
答案 2 :(得分:0)
这有一些方法:
((?:apple|orange|juice)\S)|(\S(?:apple|orange|juice))|(\S(?:apple|orange|juice)\S)
答案 3 :(得分:0)
\A(?!apple\Z|juice\Z|orange\Z).*\Z
将匹配整个字符串,除非它只包含一个禁用词。
或者,如果您没有使用Ruby,或者您确定您的字符串不包含换行符,或者您设置了^
和$
在开头/结尾不匹配的选项行
^(?!apple$|juice$|orange$).*$
也可以。
答案 4 :(得分:0)
这里有一些简单的复制粘贴代码,其作用不仅限于精确单词例外。
在以下正则表达式中,仅将全部大写部分替换为您的正则表达式。
Python正则表达式pattern = r"REGEX_BEFORE(?>(?P<exceptions_group_1>EXCEPTION_PATTERN)|YOUR_NORMAL_PATTERN)(?(exceptions_group_1)always(?<=fail)|)REGEX_AFTER"
Ruby正则表达式
pattern = /REGEX_BEFORE(?>(?<exceptions_group_1>EXCEPTION_PATTERN)|YOUR_NORMAL_PATTERN)(?(<exceptions_group_1>)always(?<=fail)|)REGEX_AFTER/
PCRE正则表达式
REGEX_BEFORE(?>(?<exceptions_group_1>EXCEPTION_PATTERN)|YOUR_NORMAL_PATTERN)(?(exceptions_group_1)always(?<=fail)|)REGEX_AFTER
的JavaScript
从2020年6月17日起是不可能的,并且在不久的将来将不可能。
REGEX_BEFORE = \ b
YOUR_NORMAL_PATTERN = \ w +
REGEX_AFTER =
EXCEPTION_PATTERN =(苹果|橙色|果汁)
pattern = r"\b(?>(?P<exceptions_group_1>(apple|orange|juice))|\w+)(?(exceptions_group_1)always(?<=fail)|)"
Ruby正则表达式
pattern = /\b(?>(?<exceptions_group_1>(apple|orange|juice))|\w+)(?(<exceptions_group_1>)always(?<=fail)|)/
PCRE正则表达式
\b(?>(?<exceptions_group_1>(apple|orange|juice))|\w+)(?(exceptions_group_1)always(?<=fail)|)
这使用了相当复杂的正则表达式,即原子组,条件,后向和命名组。
(?>
是原子组的开始,这意味着它不允许回溯:这意味着,如果该组匹配一次,但后来由于后向失败而无效,则整个组将不匹配。 (在这种情况下,我们希望这种行为)。
(?<exceptions_group_1>
创建一个命名的捕获组。它比使用数字更容易。请注意,该模式首先尝试查找异常,然后在找不到异常的情况下退回到普通模式。
请注意,原子模式首先尝试查找异常,然后在找不到异常的情况下返回常规模式。
真正的魔力在(?(exceptions_group_1)
中。这是有条件的询问exceptions_group_1是否成功匹配。如果是,那么它将尝试查找always(?<=fail)
。这种模式(如它所说)将始终失败,因为它会寻找“始终”一词,然后检查“是否会“一直” =“失败””,这是永远不会失败的。
因为有条件的失败,这意味着原子组失败,并且因为它是原子的,这意味着其已经匹配了异常,因此不允许其回溯(试图查找正常模式)。
这绝对不是打算使用这些工具的方式,但它应该可靠且有效地工作。
/\b(?>(?<exceptions_group_1>(apple|orange|juice))|\w+)(?(<exceptions_group_1>)always(?<=fail)|)/
与其他方法不同,可以修改此方法以拒绝任何模式,例如不包含子字符串“ apple”,“ orange”或“ juice”的任何单词。
/\b(?>(?<exceptions_group_1>\w*(apple|orange|juice))|\w+)(?(<exceptions_group_1>)always(?<=fail)|)/
答案 5 :(得分:-1)
类似(PHP)
$input = "The orange apple gave juice";
if(preg_match("your regex for validating") && !preg_match("/apple|orange|juice/", $input))
{
// it's ok;
}
else
{
//throw validation error
}