【问题标题】:Java regex help needed to split string please! How to ignore an empty line?拆分字符串需要 Java 正则表达式帮助!如何忽略空行?
【发布时间】:2010-08-03 09:23:58
【问题描述】:

我是个正则表达式的菜鸟,我需要拆分字符串的帮助。我正在输入以下数据

665  11% R     1    908K    388K  fg root     top
 61   1% S    42 152404K  29716K  fg system   system_server
 38   0% S     1    840K    340K  fg root     /system/bin/qemud
114   0% S    16 120160K  19156K  fg radio    com.android.phone

这不过是您的常规顶级输出。我打算做的是选择像

这样的条目
655 11% R 1 fg root top

现在我用来执行以下操作的代码是

while ((inputLine = in.readLine()) != null) 
{
  String[] segs= inputLine.split("[ ]+");
  str[i] = segs[0]+" "+segs[1]+" "+segs[2]+" "+
           segs[3]+" "+segs[6]+" "+segs[7]+" "+segs[8];
  Log.v("TOP Output", str[i]);
  i++; j++;
}

但我面临的问题是,我上 logcat 是

java.lang.ArrayIndexOutOfBoundsException

我哪里出错了,我可以做些什么来防止这种情况发生。感谢您的帮助。

编辑:阅读 cmets 后,我意识到我的输出中有几行空行。因此,在这种情况下,我应该如何忽略这些行。我知道我应该匹配一个案例,但我不确定表达式或语法!

【问题讨论】:

  • 首先,检查segs 数组的内容。它分为多少个元素?
  • 您可能正在读取文件末尾的空行。
  • 其实我读的是一个空行,但是那样的话真的重要吗?
  • 它不是从零开始初始化,还是我应该从1开始!?

标签: java android regex


【解决方案1】:

您不需要字符类(方括号)。空格是正则表达式中的常规字符,所以:

String[] segs = inputLine.split(" +");

除此之外,假设没有范围检查的数组索引是不好的风格,ArrayIndexOutOfBoundsException 正是你所要求的。

最好明确地做到这一点:

String re = "^\\s*(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\s+(\\S+)\\s+(\\S+)\\s*$";
Pattern p = Pattern.compile(re, Pattern.MULTILINE);
Matcher m = p.matcher(yourInputString);

while (m.find())
{
   // do stuff with m.group(1) through m.group(9)
}

这样可以保证您匹配的每一行都满足您的期望,并且每个匹配器组也包含您的期望。

免责声明:我并不为那个正则表达式感到特别自豪。实际上,这很丑陋,但它说明了显式比隐式更可靠和可预测的观点。并且它有可能被改进为与所需部分匹配的版本,甚至比字符串拆分更准确。

【讨论】:

  • 对不起,我不太明白我在你的 find 函数中做什么。我对java很陌生,我只是在学习。这也照顾空行,我想从我的结果中消除它们......
  • 我在 Eclipse 中也遇到了 String re 的无效序列错误。我做错了什么!?
  • 哎呀。这些反斜杠必须被转义。我的错,请参阅更正的答案。查看regular-expressions.info/java.html 了解更多关于 Java 正则表达式的信息。
  • 是的,谢谢,我明白了,还有一些错误,我会把代码放在问题中。但是选择了你的答案!谢谢,shouvik...
【解决方案2】:

使用下面的正则表达式,检查数组的长度,每一行! 并且还可以考虑使用 StringBuilder 或 StringBuffer 而不是连接。

 String[] s = inputLine.split("[\\s\\t]+");

【讨论】:

  • 如果我有一个空行,这将如何帮助我在我的字符串条目中拒绝这一行?
  • 添加条件 => (line != null && line.trim().length() > 0)
  • 仅供参考,您无需明确匹配\t\s 已经涵盖了。
  • @Alan Moore 我认为这种行为也是如此。但是当我针对字符串“665 11% R 1 908K 388K fg root top”对其进行测试时,它返回了 25 个字符串,但后来我意识到我忘记添加“+”号了 :) 谢谢!
【解决方案3】:

这个输出的一致性如何?每列总是有一个值吗?如果是这样,试试这个:

line = line.replaceFirst("(?:\s+\d+[KM]?){3}", "");

使用这种方法您不必担心空行,因为正则表达式不匹配它们。

【讨论】:

    【解决方案4】:

    在 str 实例化时要小心,它有多大,因为它是一个数组。您应该使用列表或其他任何内容,因为您不知道输入中有多少行。

    【讨论】:

    • 我猜它是一个字符串数组
    猜你喜欢
    • 2023-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多