1

我有一个文本集合,我想提取列出的所有国家的所有实例。到目前为止,我能够根据以下代码用所有国家/地区填充 Set:

  Set<String> countries = new TreeSet<String>();
  Locale[] locales = Locale.getAvailableLocales();
  for (Locale locale : locales) {
        countries.add(locale.getDisplayCountry());
  }

我当然可以为每个国家/地区创建一个正则表达式以在每一行中搜索,但我想知道我是否可以在一个正则表达式中执行此操作,即在给定的文本行中提到了哪个国家。

4

3 回答 3

2

将所有国家名称连接到一个正则表达式中:

String regex = "(";
boolean first = true;

for (String name: countries) {
    regex += (first ? "" : "|") + Pattern.quote(name);
    first = false;
}

regex += ")";

(您可以使用 编写更高效的代码StringBuffer

您将获得一个形式为: 的正则表达式,(Country1|Country2|Country3)如果文本匹配任何国家/地区名称,它将匹配。

此解决方案假定您希望将国家/地区名称完全匹配(直到空格和点)作为您从中获得的名称getDisplayCountry。您可以通过添加到正则表达式使其匹配不区分大小写(?i)

于 2012-07-25T09:59:42.873 回答
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));
}
于 2012-07-25T10:03:59.413 回答
0

如果您只是简单匹配(精确字符串匹配),那么实际上有比正则表达式更好的方法。有一种强大的字符串匹配算法,称为Aho-Corasick 算法。所以你需要做的是创建 Aho-Corasick 树并用国名填充它。然后,您可以在文本中以最佳时间复杂度搜索这些国家。这是python实现,我希望java也有一些。

于 2015-04-22T10:40:14.533 回答