在 Java 正则表达式中结合或和否定?
Combining or and negation in Java regex?
我正在尝试结合使用 "not" 和 "or" 来生成一组正则表达式匹配,如下所示:
"blah" matching "zero or more of" : "not h" or "any in b,l,a" = false
"blah" matching "zero or more of" : "any in b,l,a" or "not h" = false
"blah" matching "zero or more of" : "not n" or "any in b,l,a" = true
"blah" matching "zero or more of" : "any in b,l,a" or "not n" = true
我尝试了以下正则表达式,但它们似乎没有达到我的要求。我还包括了我对正则表达式的解释:
//first set attempt - turns out to be any of the characters within?
System.out.println("blah".matches("[bla|^h]*")); //true
System.out.println("blah".matches("[^h|bla]*")); //false
System.out.println("blah".matches("[bla|^n]*")); //false
System.out.println("blah".matches("[^n|bla]*")); //false
//second set attempt - turns out to be the literal text
System.out.println("blah".matches("(bla|^h)*")); //false
System.out.println("blah".matches("(^h|bla)*")); //false
System.out.println("blah".matches("(bla|^n)*")); //false
System.out.println("blah".matches("(^n|bla)*")); //false
//third set attempt - almost gives the right results, but it's still off somehow
System.out.println("blah".matches("[bla]|[^h]*")); //false
System.out.println("blah".matches("[^h]|[bla]*")); //false
System.out.println("blah".matches("[bla]|[^n]*")); //true
System.out.println("blah".matches("[^n]|[bla]*")); //false
所以,最后,我想知道以下问题:
- 我对上述正则表达式的解释是否正确?
- 什么是符合我的规范的四个 Java 正则表达式?
- (可选)我是否在我的正则表达式中犯了其他错误?
关于模糊的需求,我只想说明以下几点:
正则表达式细分可能类似于 ("not [abc]" 或 "bc")*,它会匹配任何类似于 bcbc...
或 ...
的字符串,其中字符不是 a
秒、b
秒或 c
秒。我只是选择 "blah" 作为一般示例,例如 "foo" 或 "bar".
对于前 2 个条件,您可以使用:
^(?:[bla]|[^h])*$
接下来的 2 个你可以使用:
^(?:[bla]|[^n])*$
正则表达式详细信息:
^
: 开始
(?:
: 启动非捕获组
[bla]
:匹配b or l or a
之一:
|
: 或
[^h]
:匹配任何非h
的字符
)*
:结束非捕获组,匹配0个或多个本组
$
:结束
RegEx Demo
请注意,对于 .matches
,锚点是隐式的,因此您可以省略 ^
和 $
。
要结合您的标准,请在非捕获组中使用单独的替代字符集 [],因此
"[bla|^h]*"
将是
(?:[bla]*|[^h]*)+
类似于"at least one occurence of (b,l,a or not h)"
请记住,与 *
匹配意味着 "may occure"(技术上为零或更多)
"not h"可以有多种写法:
(?!.*h.*)
[^h]*
"any in b,l,a"1:
[bla]*
1) 假设您的意思是 "only one of b,l,a",否则问题中的所有 4 个示例都是 true
使用 or
的组合将是:
[^h]*|[bla]*
表示“必须是不包含h
的字符串,或者必须是仅包含b
、l
和a
个字符的字符串。
在这种情况下,|
的顺序没有区别,因此 [^h]*|[bla]*
和 [bla]*|[^h]*
的效果相同。
System.out.println("blah".matches("[bla]*|[^h]*")); //false
System.out.println("blah".matches("[^h]*|[bla]*")); //false
System.out.println("blah".matches("[bla]*|[^n]*")); //true
System.out.println("blah".matches("[^n]*|[bla]*")); //true
我正在尝试结合使用 "not" 和 "or" 来生成一组正则表达式匹配,如下所示:
"blah" matching "zero or more of" : "not h" or "any in b,l,a" = false
"blah" matching "zero or more of" : "any in b,l,a" or "not h" = false
"blah" matching "zero or more of" : "not n" or "any in b,l,a" = true
"blah" matching "zero or more of" : "any in b,l,a" or "not n" = true
我尝试了以下正则表达式,但它们似乎没有达到我的要求。我还包括了我对正则表达式的解释:
//first set attempt - turns out to be any of the characters within?
System.out.println("blah".matches("[bla|^h]*")); //true
System.out.println("blah".matches("[^h|bla]*")); //false
System.out.println("blah".matches("[bla|^n]*")); //false
System.out.println("blah".matches("[^n|bla]*")); //false
//second set attempt - turns out to be the literal text
System.out.println("blah".matches("(bla|^h)*")); //false
System.out.println("blah".matches("(^h|bla)*")); //false
System.out.println("blah".matches("(bla|^n)*")); //false
System.out.println("blah".matches("(^n|bla)*")); //false
//third set attempt - almost gives the right results, but it's still off somehow
System.out.println("blah".matches("[bla]|[^h]*")); //false
System.out.println("blah".matches("[^h]|[bla]*")); //false
System.out.println("blah".matches("[bla]|[^n]*")); //true
System.out.println("blah".matches("[^n]|[bla]*")); //false
所以,最后,我想知道以下问题:
- 我对上述正则表达式的解释是否正确?
- 什么是符合我的规范的四个 Java 正则表达式?
- (可选)我是否在我的正则表达式中犯了其他错误?
关于模糊的需求,我只想说明以下几点:
正则表达式细分可能类似于 ("not [abc]" 或 "bc")*,它会匹配任何类似于 bcbc...
或 ...
的字符串,其中字符不是 a
秒、b
秒或 c
秒。我只是选择 "blah" 作为一般示例,例如 "foo" 或 "bar".
对于前 2 个条件,您可以使用:
^(?:[bla]|[^h])*$
接下来的 2 个你可以使用:
^(?:[bla]|[^n])*$
正则表达式详细信息:
^
: 开始(?:
: 启动非捕获组[bla]
:匹配b or l or a
之一:|
: 或[^h]
:匹配任何非h
的字符
)*
:结束非捕获组,匹配0个或多个本组$
:结束 RegEx Demo
请注意,对于 .matches
,锚点是隐式的,因此您可以省略 ^
和 $
。
要结合您的标准,请在非捕获组中使用单独的替代字符集 [],因此
"[bla|^h]*"
将是
(?:[bla]*|[^h]*)+
类似于"at least one occurence of (b,l,a or not h)"
请记住,与 *
匹配意味着 "may occure"(技术上为零或更多)
"not h"可以有多种写法:
(?!.*h.*)
[^h]*
"any in b,l,a"1:
[bla]*
1) 假设您的意思是 "only one of b,l,a",否则问题中的所有 4 个示例都是 true
使用 or
的组合将是:
[^h]*|[bla]*
表示“必须是不包含h
的字符串,或者必须是仅包含b
、l
和a
个字符的字符串。
在这种情况下,|
的顺序没有区别,因此 [^h]*|[bla]*
和 [bla]*|[^h]*
的效果相同。
System.out.println("blah".matches("[bla]*|[^h]*")); //false
System.out.println("blah".matches("[^h]*|[bla]*")); //false
System.out.println("blah".matches("[bla]*|[^n]*")); //true
System.out.println("blah".matches("[^n]*|[bla]*")); //true