【发布时间】:2014-09-08 21:48:21
【问题描述】:
给定一个包含逗号分隔列表的字符串,表示专有名词和类别/描述对,使用 String.split() 与 Pattern & Matcher 方法查找特定专有名词并提取相关类别的优缺点是什么/描述对?
haystack 字符串格式不会改变。它将始终包含逗号分隔的数据,形式为 PROPER_NOUN|类别/描述
两种方法的共同变量:
String haystack="EARTH|PLANET/COMFORTABLE,MARS|PLANET/HARDTOBREATHE,PLUTO|DWARF_PLANET/FARAWAY";
String needle="PLUTO";
String result=null;
使用 String.split():
for (String current : haystack.split(","))
if (current.contains(needle))
{
result=current.split("\\|")[1]);
break; // *edit* Not part of original code - added in response to comment from Pshemo
{
使用模式和匹配器:
Pattern pattern = pattern.compile("(" +needle+ "\|)(\w+/\w+)");
Matcher matches = pattern.matcher(haystack);
if (matches.find())
result=matches.group(2);
这两种方法都提供了我需要的信息。
我想知道是否有任何理由选择其中之一。我目前没有在我的项目中使用 Pattern & Matcher,所以这种方法需要从 java.util.regex
导入当然,如果有客观上“更好”的方法来解析信息,我将欢迎您的意见。
感谢您的宝贵时间!
结论
我选择了模式/匹配器方法。虽然使用正则表达式读取有点棘手,但它比 .split()/.contains()/.split() 更快,而且对我来说更重要的是,它只捕获第一个匹配项。
不管怎样,这是我不完美的基准测试的结果,以纳秒为单位,经过 100,000 次迭代:
.split()/.contains()/.split
304,212,973
Pattern/Matcher w/Pattern.compile() 为每次迭代调用
230,511,000
Pattern/Matcher w/Pattern.compile() 在迭代之前调用
111,545,646
【问题讨论】:
-
只是一个小评论:如果您是根据用户输入手动构建模式,请始终使用
Pattern.quote()转义字符串。 -
Pattern/Matcher解决方案的唯一优点是它会在找到needle|\w+/\w+时停止迭代您的输入,而split(",")将迭代整个输入,然后再次迭代,直到找到 sting包含needle。我不确定contains是否是正确的方法,除非您确定搜索到的noun永远不会作为category/description对的一部分出现。 -
@biziclop:感谢 .quote() 提示,我不知道这种方法。
-
@Pshemo:非常感谢您的 contains() 标注。不应该有重复的名词,但我和其他人一起工作,我们倾向于远离无误。如果我使用 .split() 路线,我将包含一个 'break;'
-
请注意,您的两个实现在某些输入字符串上的行为不同。例如,如果针出现在
|的右侧,或者如果左侧不包含/,则基于String.split()的实现将接受它,但不会接受Pattern实现。跨度>