3

我试图了解更多string operationsregexes。例如,这是一个给定的数组String

String [] tab = {"__09_23_HELLO","__89_2_WORLD","900_23_TRY","_34_90_SATELLITE", 
"___23_", "390"};

我在这里要做的是仅在下划线后跟一个字母后保留数据,如果找不到,请返回null。在这个例子中,我会得到这个:

HELLO WORLD TRY SATELLITE null null

所以我写了这个递归函数:

public String getName(String string, int i)
{
    if(i == string.length()-1) return null;
    if(string.charAt(i) != '_' || 
      (string.charAt(i) == '_' && !Character.isLetter(string.charAt(i+1)))) 
        return getName(string, i+1);
    else
        return string.substring(i+1);
}

而且效果很好。但是由于我不知道很多正则表达式(也许还有其他方法?),我想知道我是否可以使用正则表达式来做到这一点,以及它是否会在处理大量数据时更快地进行。

感谢您的回答。

4

4 回答 4

3

虽然您可以使用递归函数,但使用不同的方法肯定会更快:

  • 要么我会使用循环(类似于你的方法,但使用循环而不是递归来增加计数器i)。

  • 或者,按照您的建议使用正则表达式匹配来编写它。

这两种可能性中的哪一种更快并不容易确定,但我猜想正则表达式更快,除非你的循环代码非常聪明并且尽可能少。要找出没有办法对这两种方法进行编码并对其进行基准测试......

于 2013-03-07T09:35:27.270 回答
2

JIT 很难优化递归调用(参见这篇文章),所以我尽量避免它。这是一个正则表达式解决方案(结合子字符串,正如您对标签的预期)。

String [] tab = {"__09_23_HELLO","__89_2_WORLD","900_23_TRY","_34_90_SATELLITE",  "___23_", "390"};
Pattern pattern = Pattern.compile("_[a-zA-Z]");
for (int i = 0; i < tab.length; i++) {
    Matcher matcher = pattern.matcher(tab[i]);
    if (matcher.find()) {
        tab[i] = tab[i].substring(matcher.start() + 1);
    } else {
        tab[i] = null;
    }
}
System.out.println(Arrays.toString(tab));
于 2013-03-07T09:32:17.850 回答
2

对数组中的每个元素应用正则表达式:

/[^_\d\s]+/g
于 2013-03-07T09:37:46.493 回答
1

我创建了以下实现(它转换原始字符串数组中的值):

for (int index = 0; index < strings.length; index++) {
    String eachString = strings[index];
    int startIndex = eachString.lastIndexOf('_') + 1;
    if (startIndex > 0 && eachString.length() != startIndex && Character.isLetter(eachString.charAt(startIndex))) {
        strings[index] = eachString.substring(startIndex);
    } else {
        strings[index] = null;
    }
}
return strings;
于 2013-03-07T11:21:32.360 回答