我有一个文本集合,我想提取列出的所有国家/地区的所有实例。到目前为止,我能够根据以下代码填充所有国家/地区的Set:
Set<String> countries = new TreeSet<String>();
Locale[] locales = Locale.getAvailableLocales();
for (Locale locale : locales) {
countries.add(locale.getDisplayCountry());
}
我当然可以为每个国家制作一个正则表达式来搜索每一行,但我想知道我是否可以在一个正常的表达中这样做,即在这个给定的文本行中提到哪个国家。
答案 0 :(得分:2)
将所有国家/地区名称连接成一个正则表达式:
String regex = "(";
boolean first = true;
for (String name: countries) {
regex += (first ? "" : "|") + Pattern.quote(name);
first = false;
}
regex += ")";
(您可以使用StringBuffer
)
您将获得一个具有以下格式的正则表达式:(Country1|Country2|Country3)
,如果文本与任何国家/地区名称匹配,它将匹配。
此解决方案假定您希望将国家/地区名称(从空格和点开始)与getDisplayCountry
的名称完全匹配。您可以通过将(?i)
添加到正则表达式来使其与大小写不匹配。
答案 1 :(得分:1)
您可以通过连接用“|”分隔的所有名称来构建单个正则表达式,以指示“其中任何一个都可以”。在您的情况下,您可以构建
StringBuilder exp = new StringBuilder();
for (String s : countries) {
exp.append(exp.length() == 0 ? "(" : "|");
exp.append(s);
}
Pattern countryPattern = Pattern.compile(exp.append(")").toString());
并且,给定countryPattern,您现在可以编写以下内容来迭代所有匹配
Matcher m = countryPattern.matcher(aStringWithCountries);
while (m.find()) {
System.err.println("Found country " + m.group(1));
}
答案 2 :(得分:0)
如果你只是简单的匹配(精确的字符串匹配),那么实际上比正则表达式更好。有一个强大的字符串匹配算法Aho-Corasick algorithm。所以你需要做的是创建Aho-Corasick树并用国家名称填充它。然后,您可以在最佳时间复杂度中搜索文本中的这些国家/地区。这是python implementation,我希望java也有一些。