以下代码:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
// Create a Pattern object
Pattern r = Pattern.compile("[?:!.,;'’\"“”«»<>=()_-]+");
// Now create matcher object.
Matcher m = r.matcher("Hello,World!");
while(m.find())
System.out.println(m.group());
}
}
输出:
,
!
如果我在正则表达式(更长的连字符)中添加标点符号,使其变为:
Pattern r = Pattern.compile("[?:!.,;'’\"“”«»<>=()_-–]+");
输出变为:
ello,
orld!
有谁能告诉我为什么会出现这种奇怪的故障?
答案 0 :(得分:4)
这是因为-
和_
之间的短划线(–
)创建了一个范围,并且包含Unicode代码点介于_
和{{1之间的所有字符}}
–
是U + 005F _
是U + 2013 所以介于两者之间的所有内容都包含在范围内。这包括小写拉丁字符(范围从U + 0061到U + 007A)。
大写拉丁字符的范围从U + 0041到U + 005A,因此位于之前 U + 005F的下划线。这些被排除在角色类之外。
将短划线放在角色类的开头或结尾以解决问题。
–
或者,您可以使用反斜杠来逃避它,但我建议您坚持使用第一个/最后一个规则,因为它更容易阅读。
答案 1 :(得分:1)
一些基础知识:
所有正则表达式特殊字符都可以在类之外转义 调用其 literal 含义。
内部课程,乍一看,ascii短划线符号-
是范围操作符,
你记得。
要调用其字面含义,可以将其放在
的开头或结尾
类。
但是,正则表达式解析比你想象的要简单得多 将破折号放在一个类中的位置并不重要。
从左到右解析单个字符,单个字符代表
左边的位置。如果破折号是找到的下一个字符,则下一个字符为
字符代表正确的位置。这构成了一个简单的范围
构建内部类。
除了该构造之外的任何东西,破折号都是文字。
例如[a-c-m-o]
表示a,b,c,m,n,o和 -
因此,开头或结尾的短划线不能解析作为范围操作符,
如果它在范围之间或在一个范围之间(例如:[a-d-tovz]
)
当然在开始或结束时它更容易
确保它不被用作范围运营商。
与往常一样,在课堂上转义的任何内容都被视为文字,财产或
控制代码。
此外,属性不能是范围构造的左/右侧。
Java还有其他一些特殊的类构造,例如联合运算符和
嵌套类,但我认为范围运算符功能主要是
所有引擎都一样。