1

我知道我知道,有很多类似的问题,我可以说我读过所有这些问题。但是,我不擅长正则表达式,我无法弄清楚我需要的正则表达式。

我想在 Java 中拆分一个字符串,我有 4 个约束:

  1. 分隔符是 [.?!] (句末)
  2. 十进制数不应该被标记化
  3. 不应删除分隔符。
  4. 每个令牌的最小大小应为 5

例如,对于输入:

"Hello World! This answer worth $1.45 in U.S. dollar. Thank you."

输出将是:

[Hello World!, This answer worth $1.45 in U.S. dollar., Thank you.]

到目前为止,我通过这个正则表达式得到了三个第一个约束的答案:

text.split("(?<=[.!?])(?<!\\d)(?!\\d)");

而且我知道我应该{5,}在我的正则表达式中使用某个地方,但是我尝试的任何组合都不起作用。

对于像这样的情况:"I love U.S. How about you?"它给我一两个句子都没有关系,只要它不标记S.为一个单独的句子。

最后,感谢介绍一个好的正则表达式教程。

更新:正如Chris 在评论中提到的,使用正则表达式几乎不可能解决这样的问题(以涵盖自然语言中发生的所有情况)。但是,我发现 HamZa 的答案是壁橱,也是最有用的一个。

所以,要小心!接受的答案不会涵盖所有可能的用例!

4

2 回答 2

2

基于我以前制作的 regex的回答。
正则表达式基本上是(?<=[.?!])\s+(?=[a-z])这意味着匹配任何空格一次或多次,前面有一个.?或者!后面是[a-z](不要忘记i修饰符)。

现在让我们根据这个问题的需要对其进行修改:

  1. 我们首先将其转换为 JAVA 正则表达式:(?<=[.?!])\\s+(?=[a-z])
  2. 我们将添加i修饰符以匹配不区分大小写(?i)(?<=[.?!])\\s+(?=[a-z])
  3. 我们将把表达式放在一个积极的前瞻中,以防止“吃掉”字符(在这种情况下是分隔符):(?=(?i)(?<=[.?!])\\s+(?=[a-z]))
  4. 我们将添加一个否定的lookbehind来检查格式中是否没有缩写LETTER DOT LETTER DOT(?i)(?<=[.?!])(?<![a-z]\.[a-z]\.)\\s+(?=[a-z])

所以我们最终的正则表达式看起来像 : (?i)(?<=[.?!])(?<![a-z]\.[a-z]\.)\\s+(?=[a-z])

一些链接:

于 2013-08-16T21:22:08.343 回答
2

下一个正则表达式呢?

(?<=[.!?])(?!\w{1,5})(?<!\d)(?!\d)

例如

private static final Pattern REGEX_PATTERN = 
        Pattern.compile("(?<=[.!?])(?!\\w{1,5})(?<!\\d)(?!\\d)");

public static void main(String[] args) {
    String input = "Hello World! This answer worth $1.45 in U.S. dollar. Thank you.";

    System.out.println(java.util.Arrays.toString(
        REGEX_PATTERN.split(input)
    )); // prints "[Hello World!,  This answer worth $1.45 in U.S.,  dollar.,  Thank you.]"
}
于 2013-08-16T20:41:36.983 回答