一个简单的解决方案是将字符串拆分为破折号(“-”),然后遍历拆分部分并匹配您的关键字。
但是,当有多个匹配项或根本没有匹配项时,您必须决定该怎么做。
以下代码包含 2 个基本实现,一个在列表中收集匹配项,另一个在第一次匹配后停止。
第一个将在没有匹配项时返回一个空列表,第二个将返回 null。
import java.util.ArrayList;
import java.util.List;
public class KeywordMatcher {
private static List<String> getKeywordMatches(String s, String keyword) {
List<String> ret = new ArrayList<>();
String[] parts = s.split("-");
for (String part : parts) {
if(part.contains(keyword))
ret.add(part);
}
return ret;
}
private static String getFirstKeywordMatch(String s, String keyword) {
String[] parts = s.split("-");
for (String part : parts) {
if(part.contains(keyword))
return part;
}
return null;
}
public static void main(String[] args) {
String s ="59USD-300kg-25mb_4G-48p/min(Incl. tax)-70y-2gb+1gb_Toffee-65USD-1km(mm/hr)";
System.out.println(getKeywordMatches(s, "USD")); // prints [59USD, 65USD]
System.out.println(getKeywordMatches(s, "min")); // prints [48p/min(Incl. tax)]
System.out.println(getFirstKeywordMatch(s, "USD")); // prints 59USD
System.out.println(getFirstKeywordMatch(s, "min")); // prints 48p/min(Incl. tax)
}
}
更复杂的方法是在字符串中搜索下一个分隔符(“-”)和下一个关键字。迭代字符串直到它结束并跟踪分隔符和关键字的相对位置可以让您以更节省内存的方式获得相同的结果(因为与“拆分”方法不同,您不会在内存中创建任何新对象)。
然而,实现可能相当繁琐且难以阅读,因此我建议使用上述的一种,除非您有特定的性能要求或要搜索的字符串是 MB 大小的。
编辑:
正如我在下面评论的那样,使用正则表达式看到了另一个答案,不幸的是效率极低。
看下面的sn-p来证明:
private static String getFirstKeywordMatch(String s, String keyword) {
String[] parts = s.split("-");
for (String part : parts) {
if(part.contains(keyword))
return part;
}
return null;
}
private static String lookForKeyword(String message, String keyword) {
//System.out.println("Looking for keyword \"" + keyword + "\" in string \"" + message + "\"");
String pattern = "^.*?-?([^-]*" + keyword +"[^-]*)-?.*$";
Matcher matcher = Pattern.compile(pattern).matcher(message);
if (matcher.matches()) {
return matcher.group(1);
}
return null;
}
public static void main(String[] args) {
String s ="59USD-300kg-25mb_4G-48p/min(Incl. tax)-70y-2gb+1gb_Toffee-65USD-1km(mm/hr)";
long start=System.currentTimeMillis();
for(int i=0; i<10000000; i++) {
lookForKeyword(s, "USD");
}
System.out.println("Elapsed ms: " + (System.currentTimeMillis()-start));
start=System.currentTimeMillis();
for(int i=0; i<10000000; i++) {
getFirstKeywordMatch(s, "USD");
}
System.out.println("Elapsed ms: " + (System.currentTimeMillis()-start));
}
在我的机器上,正则表达式方法比我的方法花费大约 4 倍。
因此,虽然我通常是正则表达式大使,但不幸的是,这不是他们最好的用例之一。