为什么在Java String.split(regex)中有空标记?
我不熟悉正则表达式,我试图用它来解析由“(“,”)和空格分隔的标记。这是我的尝试:为什么在Java String.split(regex)中有空标记?,java,regex,Java,Regex,我不熟悉正则表达式,我试图用它来解析由“(“,”)和空格分隔的标记。这是我的尝试: String str = "(test (_bit1 _bit2 |bit3::&92;test#4|))"; String[] tokens = str.split("[\\s*[()]]"); for(int i = 0; i < tokens.length; i++) System.out.println(i + " : " + tokens[i]); String str=“(测试(
String str = "(test (_bit1 _bit2 |bit3::&92;test#4|))";
String[] tokens = str.split("[\\s*[()]]");
for(int i = 0; i < tokens.length; i++)
System.out.println(i + " : " + tokens[i]);
String str=“(测试(_bit1 | u bit2 | bit3::&92;测试#4 |”)”;
字符串[]标记=str.split(“[\\s*[()]”);
for(int i=0;i
我期望得到以下结果:
0:测试1:_bit1
2:_bit2
3:|比特3::&92;测试#4| 但是,实际输出中会出现两个空标记: 0:
1:测试
2:
3:_bit1
4:_bit2
5:|比特3::&92;测试#4 | 我不明白为什么我在位置0和2有两个空令牌。谁能给我一个提示吗?多谢各位 ====更新==== 答案是谁删除了它。但是我喜欢这个答案,所以我把它复制到这里作为我自己的参考 您的正则表达式[\s*[()]]与一个空格字符(\s)或其中一个匹配 字符*、(、或)。字段开头的分隔符 string(()是您获得第一个空令牌的原因。没有办法 您只需检查第一个令牌是否为空,然后忽略它 第二个空令牌位于第一个空格和 跟它走。那个在你身上,因为你用了*(零或更多) 而不是+(一个或多个)。但是修复它并不是那么简单。你想要 在空格、paren或两者上拆分,但必须确保 至少有一个字符,以其中一个为准。这可能会: \s*[()]+\s*|\s+ 但您可能也应该考虑到paren之间的空格: \s*(?:[()]+\s*)+\s+ 作为Java字符串文字,这将是: \s*(?:[()]+\s*)+\s+
您的regexp错误,请尝试以下操作: 字符串[]标记=str.split([\s(\)]+” 更新:我注意到你的代码实际上删除了括号,所以看起来你不必在括号中转义它们…不知道为什么,任何人都可以回答这个问题
新更新:感谢@Alanmore的解释,据我所知,
[]
中的括号不需要转义。您的regexp错误,请尝试以下操作:
字符串[]标记=str.split([\s(\)]+”
更新:我注意到你的代码实际上删除了括号,所以看起来你不必在括号中转义它们…不知道为什么,任何人都可以回答这个问题
新更新:感谢@Alanmore的解释,据我所知,
[]
中的括号不需要转义。索引0是第一个(
)之前的标记。索引2是输入字符串中空格和第二个(
)之间的标记
我不认为你可以避免第一个,但你可以通过使用
str.split("[\\s()]+");
索引0是第一个
(
)之前的标记。索引2是输入字符串中空格和第二个(
)之间的标记
我不认为你可以避免第一个,但你可以通过使用
str.split("[\\s()]+");
我的建议是,首先从两端删除拆分字符(以避免空字符串),然后进行拆分
String[] tokens = str.replaceAll("^[\\s()]+|[\\s()]+$", "").split("[\\s()]+");
-- replace leading or trailing--
此外,我已将拆分字符(空格,
(
)
)放在字符类[]
中。我的建议是,首先从两端删除拆分字符(以避免空字符串),然后进行拆分
String[] tokens = str.replaceAll("^[\\s()]+|[\\s()]+$", "").split("[\\s()]+");
-- replace leading or trailing--
此外,我还将拆分字符(空格,
(
)
)放在字符类[]
中。您遇到的问题是,它在分隔符之间创建一个空字符串,然后在碰到分隔符时返回它
通过添加一个额外的(例如:
String str = "(test (_bit1 (_bit2 |bit3::&92;test#4|))";
然后,输出将变为:
0 :
1 : test
2 :
3 : _bit1
4 :
5 : _bit2
6 : |bit3::&92;test#4|
我建议使用以下代码:
String str = "(test (_bit1 (_bit2 |bit3::&92;test#4|))";
String[] tokensArray = str.split("[\\s[()]*]");
ArrayList<String> tokens = new ArrayList<>();
for (String token : tokensArray) {
if (!token.isEmpty()) {
tokens.add(token);
}
}
for (int i = 0; i < tokens.size(); i++)
System.out.println(i + " : " + tokens.get(i));
String str=“(test(_bit1(_bit2 | bit3::&92;test#4 |”)”;
字符串[]tokensArray=str.split(“[\\s[()]*]”);
ArrayList标记=新的ArrayList();
for(字符串标记:tokensArray){
如果(!token.isEmpty()){
令牌。添加(令牌);
}
}
for(inti=0;i
这样做的目的是从数组中删除任何空标记,因为这些标记被认为是“不正确的”标记。您遇到的问题是,它在分隔符之间创建一个空字符串,然后在碰到分隔符时返回它 通过添加一个额外的(例如:
String str = "(test (_bit1 (_bit2 |bit3::&92;test#4|))";
然后,输出将变为:
0 :
1 : test
2 :
3 : _bit1
4 :
5 : _bit2
6 : |bit3::&92;test#4|
我建议使用以下代码:
String str = "(test (_bit1 (_bit2 |bit3::&92;test#4|))";
String[] tokensArray = str.split("[\\s[()]*]");
ArrayList<String> tokens = new ArrayList<>();
for (String token : tokensArray) {
if (!token.isEmpty()) {
tokens.add(token);
}
}
for (int i = 0; i < tokens.size(); i++)
System.out.println(i + " : " + tokens.get(i));
String str=“(test(_bit1(_bit2 | bit3::&92;test#4 |”)”;
字符串[]tokensArray=str.split(“[\\s[()]*]”);
ArrayList标记=新的ArrayList();
for(字符串标记:tokensArray){
如果(!token.isEmpty()){
令牌。添加(令牌);
}
}
for(inti=0;i
这样做的目的是从数组中删除任何空标记,因为这些标记被认为是“不正确的”令牌。谢谢,但它不起作用。此正则表达式将字符串拆分为字符。您希望使用
+
,而不是*
。您的正则表达式将在任何应用位置匹配,因为它不必使用任何字符。谢谢,但它不起作用。此正则表达式将字符串拆分为字符。您想使用+
,而不是*
。正则表达式无论在哪里应用都会匹配,因为它不需要使用任何字符。括号在字符类中时不需要转义。内部的方括号集并不重要。Java(并且只有Java)将其视为“嵌套的”字符类,它与其他东西联合在一起,所以它就像[\s*()]
。解决方案是去掉括号内的*
,在括号外添加一个+
,如