1

我非常清楚这是一个不平凡的问题。

我目前有这个:

(.*?)(!,"\s|!,"$|\.\s|\.$|\!"?\s+?|\!"?$|\?"?\s+?|\?"?$|\."\s+?|\."$|…"\s+?|…"?$)

这是匹配各种行尾位和拆分句子/段落。它做得很好。

但是,鉴于这句话:

Hello, Dr. Smith. How are you?

我想把它分成:

  1. Hello, Dr. Smith.
  2. How are you?

我现有的解决方案会产生类似的东西:

  1. Hello, Dr.
  2. Smith.
  3. How are you?

有一整套(负面)匹配的称呼:

Dr.|Prof.|Mr.|Mrs.|Ms.

任何想法如何做到这一点?

4

1 回答 1

0

我怀疑你正在盯着一个兔子洞。如果您选择走这条路,请为一些无法预料的挑战做好准备。

至于您最直接的要求,请列出您的非拆分匹配项,然后使用(*SKIP)(*FAIL)丢弃这些匹配项并继续匹配应该触发拆分点的字符串。

\K将重置全字符串匹配。这意味着之前匹配的字符不会在爆炸中被删除。制作这些元素时只会消耗空白字符。

代码:(演示

$text = <<<TEXT
Dr. Di MacKusa is a doctor.  Do you know her?!?  She live on 1 Doctor Dr. Doctorsville in the U.S.A. Mr. MacKusa married Dr. Di.
TEXT;

var_export(
    preg_split(
        '~(?:Ms|Dr|Mrs?|Prof)\.(*SKIP)(*FAIL)|[?!.]+\K\s+~',
        $text,
        0,
        PREG_SPLIT_NO_EMPTY
    )
);

输出:

array (
  0 => 'Dr. Di MacKusa is a doctor.',
  1 => 'Do you know her?!?',
  2 => 'She live on 1 Doctor Dr. Doctorsville in the U.S.A.',
  3 => 'Mr. MacKusa married Dr. Di.',
)

通过更全面的示例文本,我可以改进我的模式。我的模式是一个相当简单的解决方案,我们尚未设计为正确处理引用的文本。

于 2021-01-05T04:21:53.860 回答