帮助更好地解析Java中String的数字

Eth*_*man 5 java regex string readability literate-programming

我有一个包含数字和字母的字符串.我希望将字符串分成连续的数字块和连续的字母块.

考虑字符串"34A312O5M444123A".

我想输出:["34","A","312","O","5","M","444123","A"]

我的代码有效,看起来像:

List<String> digitsAsElements(String str){
  StringBuilder digitCollector = new StringBuilder();

  List<String> output = new ArrayList<String>();

  for (int i = 0; i < str.length(); i++){
    char cChar = str.charAt(i);

    if (Character.isDigit(cChar))
       digitCollector.append(cChar);
    else{
      output.add(digitCollector.toString());
      output.add(""+cChar);

      digitCollector = new StringBuilder();
    }         
  }

  return output;
}
Run Code Online (Sandbox Code Playgroud)

我考虑拆分str两次得到一个包含所有数字块的数组和一个包含所有字母块的数组.然后合并结果.我避开了它,因为它会损害可读性.

我故意避免用正则表达式模式解决这个问题,因为我发现正则表达式模式是可读性的主要障碍.

  • 调试器不能很好地处理它们.
  • 它们会中断某人阅读源代码的流程.
  • 加时正则表达式有机地成长并成为怪物.
  • 他们非常不直观.

我的问题是:

  • 我怎样才能提高上述代码的可读性?
  • 有一个更好的方法吗?一个优雅地解决这个问题的Util类.
  • 你在哪里画一个使用regEx和编写一些简单的东西到我上面写的内容之间的界限?
  • 如何提高regExes的可读性/可维护性?

Joe*_*oey 13

对于这个特殊的任务,我总是使用正则表达式而不是手写类似的东西.上面给出的代码,至少对我来说,比简单的正则表达式((\d+|[^\d]+)在这种情况下,就我所见)而言,可读性较差.

您可能希望避免编写超过几行的正则表达式.这些可能并且通常是不可读的并且难以理解,但代码也可以替换为!解析器几乎从不漂亮,你通常比阅读原始语法更好,而不是试图理解生成的(或手写的)解析器.同样的(imho)用于正则表达式,它只是对常规语法的简明描述.

所以,一般来说,我会说禁止正则表达式支持你在问题中给出的代码听起来像一个非常愚蠢的想法.正则表达式只是一种工具,仅此而已,仅此而已.如果其他东西能更好地进行文本解析(例如,真正的解析器,某些子串魔法等),那么就使用它.但是不要因为你对他们感到不舒服而抛弃可能性 - 其他人可能在处理这些问题时遇到的问题较少,所有人都能够学习.

编辑:mmyers评论后更新了正则表达式.


bra*_*ter 7

对于实用程序类,请查看java.util.Scanner.关于如何解决问题,有很多选择.我对你的问题有一些评论.

调试器不能很好地处理它们(正则表达式)

正则表达式是否有效取决于数据中的内容.您可以使用一些很好的插件来帮助您构建正则表达式,例如QuickREx for Eclipse,调试器实际上是否可以帮助您为数据编写正确的解析器?

它们会中断某人阅读源代码的流程.

我想这取决于你对它们的舒适程度.就个人而言,我宁愿阅读一个合理的正则表达式而不是50多行字符串解析代码,但也许这是个人的事情.

加时正则表达式有机地成长并成为怪物.

我猜他们可能,但这可能是他们生活的代码变得无关紧要的问题.如果源数据的复杂性在增加,您可能需要密切关注是否需要更具表现力的解决方案(可能是像ANTLR这样的解析器生成器)

他们非常不直观.

它们是模式匹配语言.我会说他们在这种情况下非常直观.

我怎样才能提高上述代码的可读性?

不确定,除了使用正则表达式.

有一个更好的方法吗?一个优雅地解决这个问题的Util类.

上面提到过java.util.Scanner.

你在哪里画一个使用regEx和编写一些简单的东西到我上面写的内容之间的界限?

就个人而言,我使用正则表达式来做任何相当简单的事情.

如何提高regExes的可读性/可维护性?

在扩展之前要仔细考虑,特别注意对代码和正则表达式进行详细评论,以便清楚地了解您正在做什么.


Ala*_*ore 5

如果它意味着在一行代码中解决问题,您是否愿意使用正则表达式?

// Split at any position that's either:
// preceded by a digit and followed by a non-digit, or
// preceded by a non-digit and followed by a digit.
String[] parts = str.split("(?<=\\d)(?=\\D)|(?<=\\D)(?=\\d)");
Run Code Online (Sandbox Code Playgroud)

通过评论来解释正则表达式,我认为这比任何非正则表达式解决方案(或任何其他正则表达式解决方案)更具可读性.