我正在尝试了解更多string operations
和regexes
。
例如,这是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);
}
效果很好。但是,由于我不知道很多正则表达式(也许还有其他方法吗?),我想知道我是否可以使用正则表达式做到这一点,并且如果它会以大量数据更快地进行。
感谢您的回答。
答案 0 :(得分:3)
虽然你可以使用递归函数,但使用不同的方法肯定会更快:
要么我会使用一个循环(类似于你的方法,但使用循环而不是递归来增加计数器i
)。
或者,按照建议使用正则表达式匹配来编写它。
这两种可能性中的哪一种更快并不容易决定,但我猜想正则表达式更快,除非你的循环代码非常聪明且尽可能少。要找出没有办法编写这两种方法并对其进行基准测试......
答案 1 :(得分:2)
JIT很难优化递归调用(请参阅this article),因此我尽可能避免使用它。这是一个正则表达式解决方案(与子字符串结合使用,正如您对标记所预期的那样)。
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));
答案 2 :(得分:2)
为数组中的每个元素应用regEx:
/[^_\d\s]+/g
答案 3 :(得分:1)
我创建了以下实现(它转换了原始String数组中的值):
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;