【问题标题】:Regular expression to find countries in text?正则表达式在文本中查找国家?
【发布时间】:2012-07-25 09:52:55
【问题描述】:

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

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

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

【问题讨论】:

  • 我认为找到多个匹配项是可以的。另外,请记住,某些国家/地区有多种拼写方式,任何大小的大多数文本都会出现拼写错误,并且某些国家/地区名称也是有效的非国家/地区单词或单词的一部分...

标签: java regex country


【解决方案1】:

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

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

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

regex += ")";

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

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

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

【讨论】:

    【解决方案2】:

    您可以通过连接用“|”分隔的所有名称来构建单个正则表达式,以表示“其中任何一个都可以”。在您的情况下,您可以构建

    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));
    }
    

    【讨论】:

    • 我认为您的意思是在末尾添加一个括号,而不是管道。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2023-03-18
      • 2011-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-20
      • 1970-01-01
      相关资源
      最近更新 更多