【问题标题】:RegEx pattern with unusual unicode character and word boundaries具有异常 unicode 字符和单词边界的 RegEx 模式
【发布时间】:2016-03-05 12:10:57
【问题描述】:

我遇到了一个关于 RegEx 模式的问题,希望有人能向我解释一下:

任务是匹配对象名称并将它们从存储在对象字段之一中的描述中删除。我尝试了以下表达式:

    final String description= object.getDescrition();
    final Matcher descriptionMatcher=
        Pattern.compile("\\b" + object.getName() + "\\b", Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE)
            .matcher(description);

在代码遇到添加到名称中的“注册商标”符号之前一切正常:String name = ObjectName®

如果我删除最后一个单词边界,它会再次匹配。这种行为的原因是什么?如何改进此代码以找到所有此类特殊情况?

注意:商标符号与物品名称之间用空格隔开。

【问题讨论】:

  • 是否需要保留“注册商标”或任何特殊字符?如果没有,有一些解决方案可以在解析之前将其删除。
  • 不幸的是特殊字符必须保留^^
  • 它总是在词尾还是可以在任何地方?而 object.getName() 是 ObjectName® 吗?
  • 我可以想象一个最坏的情况,这样的字符甚至可能在任何位置。是的,object.getName() 返回字段name
  • 为什么需要为此使用正则表达式?你有一个词,你想找到它是否存在?可以Pattern.compile("\\b" + Pattern.quote(object.getName()) + "\\b", Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE)吗?

标签: java regex


【解决方案1】:

® 字符不被视为单词字符,因此您的Pattern 将不匹配。

如果你只有这种情况,一个快速而肮脏的解决方案是将它与单词边界交替:

Pattern.compile("\\b" + object.getName() + "\\b|®"

【讨论】:

  • 如果末尾有除®以外的其他字符怎么办?
  • @JFPicard 因此是“快速而肮脏”的部分:)
【解决方案2】:

在这种情况下,将您的模式更改为:

"\\b\\Q" + object.getName() + "\\E(?<=\\b|®)"

如果您需要处理更复杂的情况,请在环视中使用交替而不是单词边界。示例:

"(?<=\\s|^)\\Q" + object.getName() + "\\E(?=\\s|$)"

"(?<=\\s|^)" + Pattern.quote(object.getName()) + "(?=\\s|$)"

【讨论】:

  • 是的,环顾四周是要走的路。最后,我通过将[\\W&amp;&amp;[^-]] 添加到前瞻中来调整您的第二个解决方案(因为有时连字符用于缩写表达式)。之前应该考虑过,这是一个很大的进步。
  • @UnknownId:好的,注意[\\W&amp;&amp;[^-]]可以写成[^\\w-]
猜你喜欢
  • 2012-05-22
  • 1970-01-01
  • 2013-02-03
  • 2016-05-08
  • 2016-02-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多