可选择使用String.split()方法,在定界符的最后一次出现处拆分字符串。

5
我有一个符合以下正则表达式的字符串:^.+:[0-9]+(\.[0-9]+)*/[0-9]+$,它可以轻松地被视为(文本):(小数)/(整数)。我需要将此字符串分成三个部分。通常这很容易,但是(文本)可能包含冒号,因此我无法在任何冒号上分割 - 而是在最后一个冒号上进行分割。 .*贪婪,因此它已经做了一个相当不错的工作,但这不能作为正则表达式传递给String.split(),因为它会将我的(文本)作为定界符一部分。理想情况下,我想要的是能够返回一个包含三个字符串的String[]。对于此,我完全可以不使用String.split()。
3个回答

5

我不喜欢正则表达式(开玩笑的,我喜欢,但我不是很擅长)。

String s = "asdf:1.0/1"
String text = s.substring(0,s.lastIndexOf(":"));
String doub = s.substring(s.lastIndexOf(":")+1,text.indexOf("/"));
String inte = s.substring(text.indexOf("/")+1,s.length());

@Subs:我想跳过初始的 ( - tskuzzy
他说,这个括号 () 是为了可视化目的而存在的。不要认为这些括号是必需的。 - Subs
3
我人生中犯的第一个错误。 - tskuzzy
这与我之前的情况类似,当时我还不知道有额外冒号的可能性。我觉得需要使用正则表达式来避免未来的意外。 - Huckle

3
为什么不直接使用正则表达式?
Pattern p = Pattern.compile("^(.*):([\\d\\.]+)/(\\d+)$");
Matcher m = p.matcher( someString );
if (m.find()) {
  m.group(1); // returns the text before the colon
  m.group(2); // returns the double between the colon and the slash
  m.group(3); // returns the integer after the slash
}

或类似。模式^(.*):([\d\.]+)/(\d+)$假设三个位置实际上都有值,并且允许在双重位置上仅使用一个句点/全停止,因此您可能需要根据自己的规格进行微调。


好的,现在假设我想要更为严格地匹配数字,需要 \d+(\.\d+)*。那么我只使用 0、1、3 组是安全的吗?也就是说, sometext:other:2/4sometext:other:2.0/4 会以相同的方式分组吗? - Huckle
1
可以是1、2和4组,但您不需要担心这个。只需将新组设置为非捕获组:\d+(?:\.\d+)? - Alan Moore
group(0) 返回整个匹配的字符串。这是少数索引不从零开始的情况之一。@AlanMoore 提出了一个严格的双重正则表达式建议。 - Roddy of the Frozen Peas

1

String.split()通常用于更简单的情况,其中分隔符和格式更一致,并且您不知道要拆分多少个元素。

您的用例需要一个普通的正则表达式。 您知道字符串的格式,并且知道要收集三个值。 尝试类似以下内容的东西。

Pattern p = Pattern.compile("(.+):([0-9\\.]+)/([0-9]+)$");
Matcher m = p.matcher(myString);
if (m.find()) {
    String myText = m.group(1);
    String myFloat = m.group(2);
    String myInteger = m.group(3);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接