regex 按空格和大写字母拆分文本(PHP)

zpgglvta  于 2022-12-01  发布在  PHP
关注(0)|答案(2)|浏览(174)

我试着用句子来分解文本。这篇文本中没有点。但它包含大写字母。我使用:

<?php preg_match_all('/[A-Z][^A-Z]*?/Usu',$text,$sentences);

但是它只用大写字母来分割文本。所以我有“S”,“M”,“S”这样的句子。这是错误的。我不需要把短信这样的单词分开。请帮助。
一些澄清:

  • 我试着在每个字符串之前断开字符串的一个或多个大写字母。
  • 但我真正的任务更复杂,我正在尝试格式化文本以提高可读性。
  • 示例:一个没有html标签和换行符的空缺:“可取:AWS的经验与Docker/Kubernetes的经验”。我试图得到:“可取的:“、“AWS体验”和“与Docker/Kubernetes的体验”(我想我将能够在按空格和大写字母拆分后将非常短的字符串粘在一起,也许这是一种非常糟糕的方式,当然)。
roejwanj

roejwanj1#

我假设你想把一个字符串拆分成几段,其中的断点是零宽度的位置,紧挨在大写字母之前,而不是在大写字母之后。如果是这样,你可以使用下面的正则表达式。

(?=(?<![A-Z]|^)[A-Z])

Regex demo
可按如下方式执行:

<?php
$result = preg_split("/(?=(?<![A-Z]|^)[A-Z])/", "now is THE time to BE brave"); 
print_r($result);

PHP demo
如链接所示,这将返回

Array
(
    [0] => now is 
    [1] => THE time to 
    [2] => BE brave
)

如果字符串的第一个单词是大写的("Now"),则字符串的第一个元素将是"Now is"(即,不是空字符串”)。
PHP的正则表达式引擎执行以下操作。

(?=           # begin a positive lookahead
  (?<!        # begin a negative lookbehind
    [A-Z]     # match a capital letter
    |         # or
    ^         # match the beginning of the line
  )           # end the negative lookbehind
  [A-Z]       # match a capital letter
)             # end positive lookahead

这会尝试比对正lookahead([A-Z])中的大写字母,但如果负lookahead比对它前面的大写字母,或大写字母位于字串的开头,则比对会失败。

wb1gzix0

wb1gzix02#

你真的不应该用正则表达式来解析像自然语言这样复杂的东西,我推荐用IntlBreakIterator来代替。

$text = "Sentence 1. Sentence 2! Sentence 3? Sentence; number 4...Sentence, 5.";

$it = IntlBreakIterator::createSentenceInstance("en_US");
$it->setText($text);
$parts = $it->getPartsIterator();

foreach ($parts as $point => $sentence) {
    echo "$point => $sentence\n\n\n";
}

输出

0 => Sentence 1. 

1 => Sentence 2! 

2 => Sentence 3? 

3 => Sentence; number 4...

4 => Sentence, 5.

在正则表达式中实现用于分析单词/句子的规则可能是复杂和令人生畏的。对于语法正确的语料库来说,如果文本中没有标点符号,那么就没有合理的方法来区分一个句子与另一个句子。简单地尝试用大写字母来区分会产生很多误报,因为单词可以在中间大写。诸如专有名词和一些缩写之类句子。

相关问题