2011-04-12 215 views
7

我想匹配包含某个单词的所有字符串。像:包含unicode单词的正则表达式

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

然而图案类不编译:

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

感谢帮帮我! :)

+1

错误消息*中的模式*包含两个额外的) - 是错误消息还是您的帖子错误? – Erik 2011-04-12 21:22:47

+1

您**不得**使用'\ W','\ w','\ s','\ d','\ b','\ p {alpha}'或任何其他字符类Java正则表达式中的快捷方式,因为Java正则表达式库不符合[Unicode正则表达式的形式要求](http://unicode.org/reports/tr18/#Compatibility_Properties)。你可以用'[\ pL \ pM \ p {Nd} \'\'\'\'\'\'用\ [\ pL \ pM \ p {Nd} \ p {Nl} \ p { p {Nl} \ p {Pc}]'如果你不关心Enclosed_Alphanumerics。或者,您可以使用符合Unicode标准的正则表达式库或语言。这意味着调用ICU正则表达式库,或者调用Perl的等等。 – tchrist 2011-04-12 21:31:32

+0

你用'java -encoding UTF-8'编译了吗? – tchrist 2011-04-12 22:06:44

回答

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

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

+0

是的,但他为什么会收到错误信息?他的原始表达中没有不匹配的括号。 – aioobe 2011-04-12 21:30:16

+0

恩,没有。那'\ W'将会毁了你的一天。 – tchrist 2011-04-12 21:34:27

+0

@aioobe:好问题。我们无法知道,因为他没有发布初始化他的String regex变量的确切的Java代码。 – tchrist 2011-04-12 21:37:31

0

Unicode字符在正则表达式是一个tricky business

这里是从Pattern本文档的段落:

Unicode支持

该类如下Unicode技术报告#18:Unicode的正则表达式的准则,实施其的支持,虽然与第二级稍微不同的具体语法。

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

这样,因为我们知道:

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

写你后的模式的正确方法是:

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

延伸阅读

+0

不,我很抱歉,但是那个文档** LIES **。相信,它的确如此.Java甚至不符合Level-1标准,更不用说Level-2的声称了。 JDK7人员,他们现在明白它有多糟糕,你不能使用这些东西,诚实的,所有的RL1.2a事物都是Java中的东西;它只提供RL1.2所需的11个属性中的3个;它可以甚至没有做RL1.1的权利,它有很多严重的错误,甚至没有接近提供1级的支持, – tchrist 2011-04-12 22:06:16

+0

哈哈,难道你没有什么*更好做,比坐在等待你可以提出一个正则表达式问题,你可以投诉吗?你可以看到几乎每一个正则表达式问题,解释Java正则表达式是如何破裂的。为什么你不保持安静,除非你真的知道这个问题的答案? – aioobe 2011-04-12 22:08:16

+1

他*知道答案,更重要的是,他知道任何没有提及的答案Java的正则表达式支持有多严重,这是错误的。他不仅抱怨,他多次解释如何正确地将Unicode与Java的正则表达式类相匹配。但这是很多信息,他不能期望每一次都发布。 – 2011-04-12 22:35:05

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当然是假设当面对单词字符的时候你会这样做,而且如果你保持清楚你的非单词的粒子,它甚至可以用这种方法。

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

0

UNICODE_CHARACTER_CLASS模式也可以通过嵌入标志表达式(?u)启用

尝试:

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

但首先解决您的括号内,因为我不知道你想和什么在中间组