java - 在句子中包含句号 - 正则表达式

标签 java regex pattern-matching divide

我有 40,000 行,需要将每一行分成不同的句子。现在我使用这样的模式:

String patternStr2 = "\\s*[\"']?\\s*([A-Z0-9].*?[\\.\\?!]\\s)['\"]?\\s*";

它可以处理几乎所有的句子,但对于像这样的句子: 美国海军,第一次世界大战。 将分为两部分:美国和海军,第一次世界大战。

有什么办法可以解决这个问题吗?

最佳答案

好吧,我认为你不应该为此使用正则表达式,但我无法抗拒添加一些正则表达式。

如果这很难理解,请告诉我,我会添加一些评论......

package test;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    private static final Pattern SENTENCE_DELIMITER = 
            Pattern.compile("((.+?)((?<!\\.[A-Z])(\\.\\s)(.+))?)");
    public static void main(String[] args) {
        String lineWithOneSentence = 
                "U.S. Navy, World War I";
        String lineWithTwoSentences = 
                "U.S. Navy, World War I. U.S. Air Force, World War III.";
        Matcher matcher = SENTENCE_DELIMITER.matcher(lineWithOneSentence);
        if (matcher.matches()) {
            for (int i = 0; i <= matcher.groupCount(); i++) {
                switch (i) {
                case 0: 
                    System.out.println("WHOLE MATCH: " + matcher.group(i));
                    break;
                case 2: 
                    System.out.println("FIRST SENTENCE: "+ matcher.group(i));
                    break;
                case 5: 
                    System.out.println("SECOND SENTENCE: " + matcher.group(i));
                default:
                }

            }
        }
        matcher = SENTENCE_DELIMITER.matcher(lineWithTwoSentences);
        if (matcher.matches()) {
            for (int i = 0; i <= matcher.groupCount(); i++) {
                switch (i) {
                case 0: 
                    System.out.println("WHOLE MATCH: " + matcher.group(i));
                    break;
                case 2: 
                    System.out.println("FIRST SENTENCE: "+ matcher.group(i));
                    break;
                case 5: 
                    System.out.println("SECOND SENTENCE: " + matcher.group(i));
                default:
                }
            }
        }
    }
}

这里的解决方法是:

  • 使用组
  • 对后跟空格的点使用负向后查找,以确保它们前面不会先有点后跟大写字母(如“U*.S*._”)<

这是相当过分的,并且在某些时候可能会成为一个问题,即如果您的文本按照标点符号不连贯。


输出:

WHOLE MATCH: U.S. Navy, World War I
FIRST SENTENCE: U.S. Navy, World War I
SECOND SENTENCE: null
WHOLE MATCH: U.S. Navy, World War I. U.S. Air Force, World War III.
FIRST SENTENCE: U.S. Navy, World War I
SECOND SENTENCE: U.S. Air Force, World War III.

关于java - 在句子中包含句号 - 正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16580921/

相关文章:

swift - 在 Swift switch 中提取值

java - 套接字异常 : socket closed in accept() on ServerSocket

javascript - 包含通配符的最少字符数

html - 清理序列化 DOM 的安全正则表达式?

regex - Perl 替换

regex - Perl 字符串正则表达式 - 需要解释

haskell - 提升类型的模式匹配

java - boolean 字段上的哈希码实现

java - 解密Android RSA : Invalid Ciphertext Exception

java - UnsatisfiedLinkError: java.library.path 中没有 j3dcore-ogl