【问题标题】:Regex to split sentences [duplicate]正则表达式拆分句子[重复]
【发布时间】:2014-03-24 17:11:54
【问题描述】:

我正在使用 PHP 的 preg_split() 将段落拆分为句子。这是我正在使用的正则表达式:

(?<=[\.\?\!]|(\."))\s(?=[A-Z\s\b])

它应该匹配以标点符号开头的空格,然后是空格或大写字母。但是,它不匹配这样的情况:

A "word. ".

我希望它将它分成两部分:A "word.".,但它不匹配。如何修复正则表达式?

【问题讨论】:

  • 编写一个正则表达式很容易,该表达式将由“一个空格前面有一个标点符号,后面跟着一个空格或大写字母”,但这并不总是构成句子的开头。常见例外:缩写。 “如何将段落拆分为句子”的简短回答是,仅靠正则表达式无法做到这一点。
  • 同意。词法分析是必要的。
  • 旁注:". 不是有效的语法。对于句点,如果句子以引号结尾,句点应在引号内。因此,您不仅要求正则表达式解析正确的语法(它不能),而且要求它对不正确的语法宽容。
  • 请注意,在字符类 [] 中,您不需要(不应使用)反斜杠。
  • @Floris 好吧,我承认语言环境在规则中起作用。正则表达式不适合这项工作的更多原因!

标签: php regex


【解决方案1】:

既然你已经承认它不可能完美,这里有一个应该为你“工作”的正则表达式:

$paragraph = 'This is a sentence. "More sentence." Another? "MORE". Many more. She said "how do you do?" and I said "wtf".';
$sentences = preg_split('~([a-zA-Z]([.?!]"?|"?[.?!]))\K\s+(?=[A-Z"])~',$paragraph);

print_r($sentences);

输出:

Array
(
    [0] => This is a sentence.
    [1] => "More sentence."
    [2] => Another?
    [3] => "MORE".
    [4] => Many more.
    [5] => She said "how do you do?" and I said "wtf".
)

【讨论】:

    【解决方案2】:

    您的正则表达式与您提供的示例不匹配。

    你想用你的正则表达式匹配A "word. ".。现在正则表达式可以匹配两个空格:

    A "word. ".
     ^      ^
    

    你的正则表达式意味着:

    一个空格,前面有 [.?!] 或 ."(字面意思)(1) 后跟一个大写字母或另一个空格 ([A-Z\s\b]) (2)

    现在第一个空格前面是一个大写字母,因此根据 1 这将不匹配。

    第二个空格前面是点,所以是要匹配的候选,但后面没有大写字母或其他空格(根据2),所以没有匹配。

    解决此问题的最简单方法是将" 添加到您的前瞻中:

    (?<=[.?!]|(\."))\s(?=[A-Z\s\b"])
                                 ^
    

    但对于将段落分成句子,我怀疑这是否足够,正如 cmets 已经指出的那样。

    【讨论】:

    • 时间不早了,我以为我在句号之后匹配[A-Z\s\b](而不是空格)。谢谢!
    【解决方案3】:

    下面的表达式看起来不错:

    $arr = preg_split('#(?<=[.?!](\s|"))\s?(?=[A-Z\b"])#',$str);
    

    我测试过

    当我的朋友有一天说他喜欢深盘披萨时,我 立即定了时间回到小星身边。可以说是最好的 旧金山的深盘披萨……虽然……我不相信有很多地方 做深盘披萨。话虽这么说......它不是有史以来最好的,只是 最好的“该地区”。他们在面包皮中或在面包上使用玉米粉 烘烤表面,所以有一点额外的嘎吱声。那个存在 说……我不确定我有多喜欢披萨的玉米面质地。 我有点想要一个好的外壳,你知道吗?没有额外的东西可以尝试 让它更脆。

    结果:

    Array
    (
        [0] => When my friend said he likes deep dish pizza one day, I immediately set a time to come back to Little Star. 
        [1] => Arguably, the best deep dish pizza in SF...though...I don't believe there are many places that do deep dish pizza. 
        [2] => That being said...its not the BEST ever, just the best "for the area."
        [3] => They use cornmeal in the crust, or on the baking surface, so there's a bit of extra crunch to it. 
        [4] => That being said...I'm not sure how much I like the cornmeal texture to my pizza. 
        [5] => I kind of want just a GOOD CRUST, you know? 
        [6] => No extra stuff to try to make it more crunchy.
    )
    

    但是,当你做类似的事情时它会失败

    I met Ms. Scarlet in the library.
    

    因为. S 将被解释为您的“新行定义”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-23
      相关资源
      最近更新 更多