我对Java Regex的理解是这样。有两套元字符:
[]
内):<([{\\^-=$!|]})?*+.>
\][-&^
如果我们希望某个字符(例如连字符-
)在字符类中按字面意义进行匹配,则必须用反斜杠(\
)对其进行转义。
字符类 角色类别可能出现在其他角色中 类,并且可以由联合运算符(隐式)和 相交运算符(&&)。联合运算符表示一个类 包含至少一个操作数中的每个字符 类。相交运算符表示一个包含每个 这两个操作数类中的字符。
字符类运算符的优先级如下 最高到最低:
- 文字逃逸\ x
- 分组[...]
- 范围
- 联盟[a-e] [i-u]
- 交叉点[a-z && [aeiou]]
请注意 字符类中有效地使用了不同的元字符集 而不是角色类之外。
这是正确的理解吗?
令我惊讶的是,除了使用反斜杠之外,我们还可以使用java.util.regex.Pattern.quote()
来逃脱字符类中的第二个字符集。我认为该方法仅适用于第一组元字符。
测试程序
以下测试程序说明Pattern.quote()
和\
(以及\Q
和\E
)都可以在字符类中用引号引起来:>
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
import java.util.regex.Pattern;
public class RegexTest {
@Rule
public TestName testName = new TestName();
@Test
public void testHyphenCharClassByPatternQuote() {
String regex = "[" + Pattern.quote("-") + "]";
Pattern p = Pattern.compile(regex);
String[] tests = {
"-"
, "a"
};
for (String test : tests) {
System.out.println(testName.getMethodName() + " matching " + test + ":" + p.matcher(test).matches());
}
}
@Test
public void testHyphenCharClassByBackSlash() {
String regex = "[\\-]";
Pattern p = Pattern.compile(regex);
String[] tests = {
"-"
, "a"
};
for (String test : tests) {
System.out.println(testName.getMethodName() + " matching " + test + ":" + p.matcher(test).matches());
}
}
@Test
public void testHyphenCharClassByQE() {
String regex = "[\\Q-\\E]";
Pattern p = Pattern.compile(regex);
String[] tests = {
"-"
, "a"
};
for (String test : tests) {
System.out.println(testName.getMethodName() + " matching " + test + ":" + p.matcher(test).matches());
}
}
}
测试输出
testHyphenCharClassByQE matching -:true
testHyphenCharClassByQE matching a:false
testHyphenCharClassByBackSlash matching -:true
testHyphenCharClassByBackSlash matching a:false
testHyphenCharClassByPatternQuote matching -:true
testHyphenCharClassByPatternQuote matching a:false
答案 0 :(得分:1)
您基本上是正确的,但是pattern.quote()
方法可以正常工作。似乎使您感到困惑的是字符类范围内连字符的性质。
Pattern class doc在报价下列出了以下转义修饰符 部分:
开头的引用结束
\
没什么,但引用了以下字符
\Q
一无所有,但引用所有字符,直到\E
\E
一无所有,但以\Q
所有pattern.quote
所做的工作就是用\Q
和\E
包装输入以产生文字化的字符串。
引用quote
上的Java文档
返回指定字符串的文字模式字符串。这个 方法产生一个可用于创建模式的字符串 将匹配字符串s,就好像它是文字模式一样。
输入序列中的元字符或转义序列将给出 没有特殊含义。
从技术上讲,从\Q
(不包括)到下一个\E
(不包括)(可能包括任意数量的\Q
序列)的所有内容都被字面化。
当您在字符类中转义或引用连字符时(或放在末尾),它将失去其特殊含义,即定义一个范围,并且它变成了您自己演示的文字连字符:
String regex = "[a\\-z]";
Pattern p = Pattern.compile(regex);
String[] tests = {
"-"
, "a"
, "b"
, "z"
};
for (String test : tests) {
System.out.println(" matching " + test + ":" + p.matcher(test).matches());
}
输出:
matching -:true
matching a:true
matching b:false
matching z:true
答案 1 :(得分:0)
我现在可以确认,\Q
和\E
(以及Pattern.quote()
)除了在字符类中引用元字符 外,还将很有用外部角色类。我以为它仅适用于角色类之外,并且理解是错误的。我希望文档能更清楚地说明这一点。