如何构造一个不包含一组字符串的正则表达式。
对于这个例子,我想验证地址行1文本框,以便它不包含任何辅助地址部分,如'Apt','Bldg','Ste','Unit'等。
答案 0 :(得分:5)
可以使用正则表达式来验证字符串是否包含一组单词。这是一个经过测试的Java代码片段,带有注释的正则表达式,它正是这样做的:
if (s.matches("(?sxi)" +
"# Match string containing no 'bad' words.\n" +
"^ # Anchor to start of string.\n" +
"(?: # Step through string one char at a time.\n" +
" (?! # Negative lookahead to exclude words.\n" +
" \\b # All bad words begin on a word boundary\n" +
" (?: # List of 'bad' words NOT to be matched.\n" +
" Apt # Cannot be 'Apt',\n" +
" | Bldg # or 'Bldg',\n" +
" | Ste # or 'Ste',\n" +
" | Unit # or 'Unit'.\n" +
" ) # End list of words NOT to be matched.\n" +
" \\b # All bad words end on a word boundary\n" +
" ) # Not at the beginning of bad word.\n" +
" . # Ok. Safe to match this character.\n" +
")* # Zero or more 'not-start-of-bad-word' chars.\n" +
"$ # Anchor to end of string.")
) {
// String has no bad words.
System.out.print("OK: String has no bad words.\n");
} else {
// String has bad words.
System.out.print("ERR: String has bad words.\n");
}
这假设单词必须是“整个”单词,并且无论如何都应该识别“坏”单词。另请注意,(正如其他人已经正确说明的那样),这不如仅仅检查坏词的存在然后采用逻辑NOT那样有效。
答案 1 :(得分:0)
为什么不构造正则表达式来匹配做包含一个或多个字符串的字符串,而不是尝试构造正则表达式以匹配不包含这些子字符串的字符串他们?然后,如果该正则表达式返回true
,则表示您的字符串无效。
答案 2 :(得分:0)
更理论的答案:
确定性有限自动机与正则表达式一一对应;也就是说,对于每种常规语言,您都可以构造一个DFA,它将完全接受常规语言中包含的字符串。而且,对于每种常规语言,您都可以构造一个只与该语言中的字符串匹配的正则表达式。因此,对于任何正则表达式,您可以构造一个接受完全相同字符串的DFA,反之亦然。
通过为NFA中的每个状态组合构建DFA状态,可以将非确定性有限自动机(NFA)转换为确定性有限自动机(DFA)。 (这是| Q | 2 状态,这是一个有限数。)
根据这些知识,我们可以撤消DFA A
并生成DFA A'
,该{DAL A
接受A
拒绝的每个字符串,并拒绝|
接受的每个字符串。
这可以通过将所有结束状态转换为临时启动状态,将启动状态转换为结束状态来完成。然后,我们继续将epsilon-transitions从新的起始状态添加到这些临时开始状态中的每一个,以使其成为有效的NFA(epsilon-NFA,如果你想挑选)。然后,我们将其转变为DFA,因为我们知道我们可以做到。
唯一剩下的步骤是将我们的新DFA变成正则表达式。对此的算法非常简单:对于从开始到结束状态的每条路径,我们在正则表达式中包含*
(或)用于每个分支,串联状态的连接和{{1}}(每个循环都有kleene闭包。
答案 3 :(得分:-1)
你否定了你不想要的字符串 - 例如
"ten" !~ /one|two|three/
这会给你:
print "one" !~ /one|two|three/ --> false
print "two" !~ /one|two|three/ --> false
print "ten" !~ /one|two|three/ --> true