使用REGEX计算句子数并忽略首字母缩略词

时间:2015-04-16 11:19:53

标签: java regex

我尝试使用正则表达式计算文本中的句子数。我想出了一个regex1找到所有要点:

([^.!?\s][^.!?]*)

之后我尝试通过以下regex2找到大部分首字母缩略词:

([A-Z]+[a-z]{0,3}\.).

但是我有一些问题:

  1. 如果首字母缩写词位于句子的末尾,则可以通过regex2公式找到(例如,自公元前20,000年以来)。这不是故意的,我只想在一个句子中找到首字母缩略词。

  2. 如果我们假设,问题1已经解决,我想将两个正则表达式公式合并在一起,以便最终公式只输出实际的句子数。例如,我们可以考虑维基百科的以下文本:

  3.   

    美国国家航空航天局(NASA)是美国联邦   国家政府机构负责民用空间计划   以及航空航天研究。

         总统德怀特·艾森豪威尔成立了国家航空公司   和空间管理局(NASA)于1958年[5]具有明显的平民   鼓励和平应用(而非军事)方向   在空间科学。国家航空航天法案获得通过   1958年7月29日,解散美国宇航局的前身国民党   航空咨询委员会(NACA)。新机构成了   于1958年10月1日开始运作。[6] [7]

         

    从那时起,美国的大多数太空探索工作一直由此领导   美国宇航局,包括阿波罗登月任务,天空实验室空间   站,后来的航天飞机。目前,NASA正在支持   国际空间站正在监督国际空间站的发展   猎户座多功能机组人员,太空发射系统和   商用船员车辆。该机构也负责   发射服务计划(LSP),负责监督发射   无人驾驶NASA发射的操作和倒计时管理。

         美国宇航局的科学研究重点是通过这种方式更好地了解地球   地球观测系统,[8]通过努力推进太阳物理学   科学任务理事会的太阳物理研究计划,[9]   利用先进的机器人探索整个太阳系的物体   航天飞行任务,如New Horizo​​ns,[10]和研究   天体物理学的主题,如大爆炸,通过大帝   观察站和相关计划。[11] NASA与之分享数据   各种国家和国际组织,如来自   温室气体观测卫星。

    以上文字有9个句子。

    Regex1:12场比赛(D.,U。和S.被视为“完整停站”)

    Regex2:3匹配(D.,U。和S.)

    我现在需要的是一个更好的regex1公式,只能在一个句子中找到首字母缩略词,然后“合并”两个正则表达式以接收所有句子。

    如果合并两个公式是不可能的(出于任何合理的原因),那么只考虑问题1,因为目前我的JAVA程序使用两个公式分开:

    public void breakIntoSentences()
    {   
        //Find all points
        Pattern p = Pattern.compile("([^.!?\\s][^.!?]*)");
        Matcher m = p.matcher(content);
    
        int allPoints = 0;
        while(m.find())
            allPoints++;
    
        //Find all acronyms with length 0-4
        p = Pattern.compile("([A-Z]+[a-z]{0,3}\\.)");
        m = p.matcher(content);
    
        int allAcronyms = 0;
        while(m.find())
            allAcronyms++;
    
        numberOfSentences = allPoints - allAcronyms;        
    }
    

    提前感谢您的帮助

2 个答案:

答案 0 :(得分:1)

这是一种模式:

.+?(?:(?<![\s.]\p{Lu})[.!?]|$)

Demo

  • .+?只是为了匹配一个完整的句子。如果您只想要一个计数,则可以将其替换为.
  • (?<![\s.]\p{Lu})表示前面没有大写字母本身,后面带有空格或句点。这是在[.!?]之前使用它来检查句末。这似乎正确处理缩略语。
  • $只是为了强制开头的非贪婪.+?匹配,直到文本的结尾,以防万一文本没有&t以句号结束。

这个正则表达式处理[6][7]作为下一句的一部分。如果这不可接受,您可以在[\d\[\]]*之后添加[.!?]稍微调整一下模式。

答案 1 :(得分:0)

看起来你想要的只是在这段时间之前检查没有资本的东西。这很容易做到:

((?:[A-Z]\.|[^\.!?])+)[\.!?]

这使用任何非句末尾符号或大写后跟句点的选项。

多个字符还允许您避免录制三个句子:

  

像这样......