我知道,我知道,现在我有两个问题,但这里的正则表达式意味着我不必编写两个复杂的循环。相反,我有一个只有我理解的正则表达式,我才会受雇于yonks。
我有一个字符串,比如stack.overflow.questions[0].answer[1].postDate
,我需要得到[0]和[1],最好是数组。 “简单!”我的神经元惊呼,只需在输入字符串上使用正则表达式和split
方法;所以我想出了这个:
String[] tokens = input.split("[^\\[\\d\\]]");
产生以下内容:
[, , , , , , , , , , , , , , , , [0], , , , , , , [1]]
亲爱的,亲爱的。所以,我想,“在这种情况下replaceAll
会做什么?”:
String onlyArrayIndexes = input.replaceAll("[^\\[\\d\\]]", "");
产生:
[0][1]
嗯。为什么这样?我正在寻找一个双元素字符串数组,其中包含“[0]”作为第一个元素,“[1]”作为第二个元素。当Javadocs声明它们都按照Javadoc使用Pattern类时,为什么split在这里不起作用?
总结一下,我有两个问题:为什么split()
调用产生具有看似随机空格字符的大数组和我认为replaceAll正常工作是正确的,因为正则表达式替换所有不匹配“[”,数字和“]”的字符?我错过了什么意味着我希望他们产生类似的输出(好的就是三个,请不要回答“一个线索?”这个!)。
答案 0 :(得分:4)
从我可以看到的split
确实有效,它为您提供了一个数组,其中包含每个匹配的字符串拆分,而不是一组括号,中间有一个数字。
至于replaceAll
我认为你的假设是正确的。它删除了你想要的一切(用""
替换匹配)。
将此字符串拆分为 给定的正则表达式。
此方法就像通过调用一样工作 两个参数的分裂方法 给定表达式和限制参数 零。尾随空字符串 因此不包括在内 结果数组。
字符串“boo:and:foo”,例如, 产生以下结果 这些表达方式:
Regex Result : { "boo", "and", "foo" } o { "b", "", ":and:f" }
答案 1 :(得分:2)
这不是您问题的直接答案,但我想向您展示一个适合您需求的优秀API。
从Google Guava查看Splitter。
因此,对于您的示例,您可以像这样使用它:
Iterable<String> tokens = Splitter.onPattern("[^\\[\\d\\]]").omitEmptyStrings().trimResults().split(input);
//Now you get back an Iterable which you can iterate over. Much better than an Array.
for(String s : tokens) {
System.out.println(s);
}
这打印:
0
1
答案 2 :(得分:2)
split
在您提供的正则表达式定义的边界上进行分割,因此您收到大量条目并不奇怪 - 字符串中几乎所有字符都与您的正则表达式相匹配因此,根据定义,是应该发生拆分的边界。
replaceAll
使用您提供的替代品替换正则表达式的匹配项,在您的情况下为空字符串。
如果你想抓住0
和1
,这是一个微不足道的循环:
String text = "stack.overflow.questions[0].answer[1].postDate";
Pattern pat = Pattern.compile("\\[(\\d+)\\]");
Matcher m = pat.matcher(text);
List<String> results = new ArrayList<String>();
while (m.find()) {
results.add(m.group(1)); // Or just .group() if you want the [] as well
}
String[] tokens = results.toArray(new String[0]);
或者,如果它总是恰好两个:
String text = "stack.overflow.questions[0].answer[1].postDate";
Pattern pat = Pattern.compile(".*\\[(\\d+)\\].*\\[(\\d+)\\].*");
Matcher m = pat.matcher(text);
m.find();
String[] tokens = new String[2];
tokens[0] = m.group(1);
tokens[1] = m.group(2);
答案 3 :(得分:1)
问题是split
在这里是错误的操作。
在红宝石中,我会告诉你string.scan(/\[\d+\]/)
,它会给你数组["[0]","[1]"]
Java没有单一方法等价物,但我们可以按如下方式编写scan
方法:
public List<String> scan(String string, String regex){
List<String> list = new ArrayList<String>();
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(string);
while(matcher.find()) {
list.add(matcher.group());
}
return retval;
}
我们可以将其称为scan(string,"\\[\\d+\\]")
等效的Scala代码是:
"""\[\d+\]""".r findAllIn string