包含unicode单词的正则表达式

时间:2011-04-12 21:14:44

标签: java regex unicode character-properties

我想匹配包含某个单词的所有字符串。像:

String regex = (?:\P{L}|\W|^)(ベスパ)(?:\b|$)

但是,Pattern类不编译它:

java.util.regex.PatternSyntaxException: Unmatched closing ')' near index 39
(?:\P{L}|\W|^)((?:ベス|ベス|ヘズ)(?:パ)|パ)|ハ)゚)(?:\b|$)

我已经设置了unicode_case来编译param,不知道这里出了什么问题

final Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE| Pattern.CANON_EQ);

感谢您的帮助! :)

4 个答案:

答案 0 :(得分:1)

从给出的错误消息中看起来什么都没有,就像显示的字符串正则表达式一样,我推断出原始模式基本上如下,我可以自由地重新格式化,添加符号常量,并在前面添加行号我们可以更容易地检查和解决它。

(所有非平凡的模式始终总是(?x)模式编写 - 即使Java在这里与你对抗,你仍然应该这样做。)

  1     (?: \P{L} | \W | ^ )
  2     (
  3         (?: \N{KATAKANA LETTER BE} \N{KATAKANA LETTER SU}
  4           | \N{KATAKANA LETTER BE} \N{KATAKANA LETTER SU}
  5           | \N{KATAKANA LETTER HE} \N{KATAKANA LETTER ZU}
  6         )
  7         (?: \N{KATAKANA LETTER PA} )
  8     |
  9             \N{KATAKANA LETTER PA}
 10     )
 11 |
 12             \N{KATAKANA LETTER HA}
 13     )
 14     \N{COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK}
 15     )
 16     (?: \b | $ )

第一行和最后一行是错误的,但它们与Java的破坏正则表达式相关的语义方式是错误的。它们语法错误。

现在应该很清楚,语法问题是第13行和第15行的近括号是虚假的:它们没有相应的开括号。

尽管有第一行和最后一行,我仍然试图了解你真正想要做的是什么。为什么重复第3和第4行?这没有任何用处。我认为没有理由在第7行进行分组。

是否允许组合标记适用于上述任何内容?

至于第一行和最后一行中的错误,我是否理解您正在寻找的简单单词边界?你真的想把那些边界字符作为你的比赛的一部分包括在内,或者你只是试图建立边界?你为什么说非字母或非字?

单词字符包括字母,你知道 - 至少,根据它们的Unicode规范,即使Java确实出错了。唉,由于Java正则表达式错误,你只是包含了一堆字母,所以一旦我理解了你真正想要的东西,我们就必须重新编码。

如果你只使用了符合UTS#18的东西,它会正常工作,但正如我认为你没有(我没有提到ICU),我们必须按照我的方针修复它有previously outlined

对于非单词或字符串的开头的后视可能适用于第一个,并且对于非单词或字符串结尾的前瞻将适用于最后一个。这就是\b在面对单词字符时当然假设要做的事情,如果你不清楚你的非单词粒子,它甚至可能会以这种方式运作。

但是直到我能看到更多的原始意图,我认为我不应该多说。

答案 1 :(得分:0)

(?:\P{L}|\W|^)((?:ベス|ベス|ヘズ)(?:パ)|パ)|ハ)゚)(?:\b|$)
(            )((              )(   )   )   )  )(      )

错误消息中的模式有两个额外的')'

答案 2 :(得分:0)

正则表达式中的Unicode字符是tricky business

以下是Pattern的文档中的段落:

  

Unicode支持

     

本课程遵循Unicode技术报告#18:Unicode正则表达式指南,实现其第二级支持,但具体略有不同。

     

Java源代码中的\u2014等Unicode转义序列按照Java语言规范的3.3中的描述进行处理。这种转义序列也可以由正则表达式解析器直接实现,这样Unicode转义就可以用在从文件或键盘读取的表达式中。 因此字符串"\u2014""\\u2014"虽然不相等,但会编译成相同的模式,它匹配具有十六进制值0x2014的字符。

因此,我们知道:

  • = \u3049
  • = \u30B9
  • = \u30D1

编写您所追求的模式的正确方法是:

String regex = "(?:\\P{L}|\\W|^)(\\u30d9\\u30B9\\u30D1)(?:\\b|$)";

进一步阅读

答案 3 :(得分:0)

也可以通过嵌入式标志表达式(?U)

启用UNICODE_CHARACTER_CLASS模式

尝试:

(?U)(?:\P{L}|\W|^)((?:ベス|ベス|ヘズ)(?:パ)|パ)|ハ)゚)(?:\b|$)

但是先修好你的括号,因为我不知道你想要进出中间组的内容