【问题标题】:Parsing a string with [3:0] substring in it解析带有 [3:0] 子字符串的字符串
【发布时间】:2015-09-28 21:52:03
【问题描述】:

我想将字符串中的两个数字存储到两个不同的变量中 - 例如,“[3:0]”中的 var1 = 3 和 var2 = 0。我有以下代码sn-p:

String myStr = "[3:0]";
if (myStr.trim().matches("\\[(\\d+)\\]")) {
    // Do something.
    // If it enter the here, here I want to store 3 and 0 in different variables or an array
} 

是否可以使用拆分和正则表达式来做到这一点?

【问题讨论】:

  • 您甚至不需要正则表达式。只需拆分:,删除0th 元素中的第一个字符和1st 元素中的最后一个字符即可。

标签: java regex string pattern-matching match


【解决方案1】:

不要打电话给trim()。改为增强您的正则表达式。

您的正则表达式缺少: 的模式和第二个数字,您不需要转义]

要捕获匹配的数字,您需要Matcher

String myStr = "  [3:0]  ";
Matcher m = Pattern.compile("\\s*\\[(\\d+):(\\d+)]\\s*").matcher(myStr);
if (m.matches())
    System.out.println(m.group(1) + ", " + m.group(2));

输出

3, 0

【讨论】:

  • 如果 OP 必须 验证输入,那么这个解决方案是正确的选择。它会简单地使用 Matcher 为我们完成所有工作,即存储我们感兴趣的值。+1.
【解决方案2】:

您可以使用replaceAllsplit

String myStr = "[3:0]";
if(myStr.trim().matches("\\[\\d+:\\d+\\]") {
   String[] numbers = myStr.replaceAll("[\\[\\]]","").split(":");
}

此外,你的regExp匹配String应该是\\[\\d+:\\d+\\],如果你想避免trim你可以在开头和结尾添加\\s+来匹配空格。但是trim还不错.

编辑

按照 cmets 中 Andreas 的建议,

String myStr = "[3:0]";
String regExp = "\\[(\\d+):(\\d+)\\]";
Pattern pattern = Pattern.compile(regExp);
Matcher matcher = pattern.matcher(myStr.trim());

if(matcher.find()) {
    int a = Integer.parseInt(matcher.group(1));
    int b = Integer.parseInt(matcher.group(2));
    System.out.println(a + " : " + b);
}

输出

3 : 0

【讨论】:

  • OP 使用的正则表达式的优点是,与模式不匹配的输入将简单地跳过 if 语句,正如 OP 可能的意图,而此代码会做出奇怪/糟糕的反应/fail 无效输入。
  • 既然你要运行正则表达式,为什么不让它返回匹配的值,而不是运行另一个 两个 正则表达式来获取它们?
【解决方案3】:

没有任何正则表达式你可以这样做:

// this will remove the braces [ and ] and just leave "3:0"
String numberString= myString.trim().replace("[", "").replace("]",""); 

// this will split the string in everything before the : and everything after the : (so two values as an array)
String[] numbers = numberString.split(":"); 

// get the first value and parse it as a number "3" will become a simple 3
int firstNumber = Integer.parseInt(numbers[0]) ; 

// get the second value and parse it from "0" to a plain 0 
int secondNumber = Integer.parseInt(numbers[1]); 

解析数字时要小心,具体取决于您的输入字符串以及可能存在的其他可能性(例如“3:12”是可以的,但“3:02”可能会引发错误)。

【讨论】:

  • OP 使用的正则表达式的优势在于,与模式不匹配的输入将简单地跳过 if 语句,正如 OP 可能的意图,而此代码会做出奇怪/糟糕的反应/fail 无效输入。
  • @Andreas:你是绝对正确的。正则表达式在这里要好得多。我只是想表明可以在没有正则表达式的情况下获得数字(正如 kon 在他的评论中指出的那样)。它可能不那么令人敬畏,但可能更容易理解:)
【解决方案4】:

如果您不需要验证输入并且只想从中获取数字,您可以简单地找到您感兴趣的 indexOf(":")substring 部分,其中是:

  • [(位于位置0)到:
  • : 的索引到](其位置等于字符串-1 的长度)

您的代码可能看起来像

String text = "[3:0]";
int colonIndex = text.indexOf(':');
String first = text.substring(1, colonIndex);
String second = text.substring(colonIndex + 1, text.length() - 1);

【讨论】:

  • OP 使用的正则表达式的优势在于,与模式不匹配的输入将简单地跳过 if 语句,正如 OP 可能的意图,而此代码会做出奇怪/糟糕的反应/fail 无效输入。
  • @Andreas 我没有说 OP 应该跳过 matches 部分。我的答案是可以在 if 块内使用的解决方案(更正后)。
  • 您的代码通过包含 myStr 声明(您将其重命名为 text)隐式替换了 if 语句。如果文本有前导空格,硬编码1 将不起作用,if 语句中的trim() 表示可能会发生这种情况。
  • @Andreas True,这就是为什么我更新了我的答案以表明它是基于我们确信输入是有效形式的假设。如果不是,并且需要使用 Matcher 进行额外验证,这将是正确的解决方案,因为它可以让我们将重要部分存储在捕获组中(您已经为此获得了我的 +1)。
猜你喜欢
  • 2010-12-05
  • 1970-01-01
  • 2011-11-27
  • 1970-01-01
  • 1970-01-01
  • 2020-11-20
  • 2015-01-13
  • 1970-01-01
相关资源
最近更新 更多