【问题标题】:Latin Regex with symbols带有符号的拉丁正则表达式
【发布时间】:2013-01-27 18:51:53
【问题描述】:

我需要拆分文本并仅获取单词、数字和带连字符的组合词。我还需要获取拉丁词,然后我使用了\p{L},它给了我 é、ú ü ã 等等。例子是:

String myText = "Some latin text with symbols, ? 987 (A la pointe sud-est de l'île se dresse la cathédrale Notre-Dame qui fut lors de son achèvement en 1330 l'une des plus grandes cathédrales d'occident) : ! @ # $ % ^& * ( ) + - _ #$% "  ' : ; > < / \  | ,  here some is wrong… * + () e -"

Pattern pattern = Pattern.compile("[^\\p{L}+(\\-\\p{L}+)*\\d]+");
String words[] = pattern.split( myText );

这个正则表达式有什么问题?为什么它匹配 "(""+""-""*""|" 等符号?

一些结果是:

dresse     // OK
sud-est    // OK
occident)  // WRONG
987        // OK
()         // WRONG
(a         // WRONG
*          // WRONG
-          // WRONG
+          // WRONG
(          // WRONG
|          // WRONG

正则表达式的解释是:

[^\p{L}+(\-\p{L}+)*\d]+

 * Word separator will be:
 *     [^  ...  ]  No sequence in:
 *     \p{L}+        Any latin letter
 *     (\-\p{L}+)*   Optionally hyphenated
 *     \d            or numbers
 *     [ ... ]+      once or more.

【问题讨论】:

  • 您对正则表达式的理解不正确。 [] 是字符类,只会匹配单个字符。

标签: java regex split symbols latin


【解决方案1】:

如果我对您的要求的理解是正确的,这个正则表达式将符合您的要求:

"\\p{IsLatin}+(?:-\\p{IsLatin}+)*|\\d+"

它将匹配:

  • Unicode Latin script 字符的连续序列。我将其限制为拉丁文,因为\p{L} 将匹配 any 脚本中的字母。如果您的 Java 版本不支持该语法,请将 \\p{IsLatin} 更改为 \\pL
  • 或几个这样的序列,连字符
  • 或连续的十进制数字序列 (0-9)

上面的正则表达式是通过调用Pattern.compile来使用的,调用matcher(String input)得到一个Matcher对象,并使用循环查找匹配。

Pattern pattern = Pattern.compile("\\p{IsLatin}+(?:-\\p{IsLatin}+)*|\\d+");
Matcher matcher = pattern.matcher(inputString);

while (matcher.find()) {
    System.out.println(matcher.group());
}

如果你想允许带有撇号的单词'

"\\p{IsLatin}+(?:['\\-]\\p{IsLatin}+)*|\\d+"

我还在字符类['\\-] 中转义-,以防您想添加更多内容。实际上- 不需要转义,如果它是字符类中的第一个或最后一个,但为了安全起见,我还是转义了它。

【讨论】:

  • 它给了我一个错误:Unknown character property name {Latin} near index 12 [^\p{IsLatin}+(?:-\p{IsLatin}+)*|\d+]跨度>
  • @ManoelMerc:代码可以在 Java 7 上运行。如果您的版本不支持它,那么您可以恢复到\\p{L}。并且不要修改正则表达式!
  • 好的!我们就快到了!我可以毫无错误地得到所有单词!非常感谢!但是管道符号“|”也作为一个词匹配。我解决不了!这是我的代码: Pattern pattern = Pattern.compile("\\p{L}+(?:-\\p{L}+)*|\\d+");匹配器 matcher = pattern.matcher( strText.toLowerCase() ); ArrayList 单词 = new ArrayList(); while(matcher.find()) { words.add(matcher.group()); } return words.toArray(new String[words.size()]);
  • @ManoelMerc:| 永远不会匹配为一个单词。这只是正则表达式中的交替。
  • 一些结果是: "dresse" // OK "sud-est" // OK "|" // 错误 编译器认为管道“|”是一个词,它不是。
【解决方案2】:

如果字符类的左括号后跟^,则该类中列出的字符是不允许的。因此,您的正则表达式允许 Unicode 字母、+(-)* 和数字出现一次或多次之外的任何内容。

请注意,+()* 等字符在字符类中没有任何特殊含义。

pattern.split 的作用是将字符串拆分为匹配正则表达式的模式。您的正则表达式匹配空格,因此每次出现一个或多个空格时都会发生拆分。所以结果会是这样。

例如考虑这个

Pattern pattern = Pattern.compile("a");
    for (String s : pattern.split("sda  a  f  g")) {
        System.out.println("==>"+s);
    }

输出将是

==>sd

==>

==> fg

【讨论】:

  • 是的,它是除此之外的任何东西,因为它用于分割文本。参见:pattern.split(myText);
  • @ManoelMerc 我认为你误解了 pattern.split
【解决方案3】:

带有[] 的正则表达式集描述只能包含字母、类(\p{...})、序列(例如a-z)和补码符号(^)。您必须将您正在使用的其他魔法字符 (+*()) 放在 [ ] 块之外。

【讨论】:

  • 我已将其更改为"\(+|\)+|\*+|\\|+|\\-+|\\++|[^\\p{L} +(\\-\\p{L}+)*\\d]+",但它现在匹配空字符串和管道符号“|”无论如何都匹配... :-(
猜你喜欢
  • 2018-06-21
  • 2018-10-13
  • 1970-01-01
  • 2016-05-13
  • 1970-01-01
  • 2014-12-20
  • 2013-04-08
  • 2015-07-09
  • 1970-01-01
相关资源
最近更新 更多