我需要通过空格、标点符号、换行符将文本分解成数组。以下是示例文本:
男人的夹克是绿色的。 他是现代历史上最大的明星,骑自行车的速度非常快(每小时230公里)。怎么可能?!他用的是什么自行车? 他的自行车的半自动齿轮非常昂贵,显着有助于达到该速度。有些人(或者很多人)声称他是世界上最快的!"我看到他骑自行车了!" 约翰·迪尔先生说话。"他设定的速度是每小时133.78公里",这听起来令人难以置信;听起来很骗人。
我已经有了这样做的正则表达式:
preg_split('/(?<=s)|(?<=w)(?=[.,:;!?()-])|(?<=[.,!()?x{201C}])(?=[^ ])/u', $text);
但目前它将以下semi-automatic
拆分为两个词,而它必须保持一个词。如果破折号旁边有空格,如semi - automatic
,那么这应该是三个词。我不太明白这个正则表达式是如何工作的,所以任何帮助都值得赞赏。
第二个问题是,如果文本包含换行符,它会捕获换行符,但也会创建冗余元素。请参阅示例 - 元素 [8] 和 [9]。元素 [8] 是多余的。我该如何解决它?
我还没有测试以下内容。
首先让我们更改正则表达式:
/[.,:;!?()s]|(?<=s)-(?=s)/u
解释:
[.,:;!?()s]
- 标点符号拆分
|(?<=s)-(?=s)
-(交替)在-
两侧各有空格的-
上拆分
接下来,对结果执行array_filter()
,删除空|假元素
编辑:
要保留标点符号,请使用:
/(?=[.,:;!?()s])|(?<=s)-(?=s)/u
我只是用展望包围了角色类
编辑2:
/s|(?=[.,:;!?)])|(?<=s[("])|(?<=s)-(?=s)/u
编辑3:
s|(?<=s)-(?=s)|(?<=w)(?=[.,:;!?])|(?<=[.,"!()?x{201C}])(?=[^ ])
编辑4:
s|(?<=s)-(?=s)|(?<=w)(?=[.,:;!?)])|(?<=[.,"!()?x{201C}])(?=[^ ])
解释:
哦,天哪,我的头今天不在比赛中。你的正则表达式几乎就在那里,只需要一两个模组,所以这是最终的正则表达式。
/s|(?<=w)(?=[.,:;!?)])|(?<=[.,"!()?x{201C}])/u
注意:环视只是匹配某些东西,它们消耗零字符,因此您可能会遇到"零宽度断言"术语。如果我们不使用环视,正则表达式引擎将匹配该字符并将其从匹配中删除。管道元字符|
是一个OR
,在正则表达式术语中是一个alternate
模式。
s
- 匹配空格字符。我们在环顾四周时不需要它,因为我们无论如何都想删除它。
(?<=w)(?=[.,:;!?)])
- OR 匹配单词字符的正面后瞻w
后跟以下任何标点符号的正面前瞻.,:;!?)
。
(?<=[.,"!()?x{201C}])
- OR 匹配以下标点符号字符.,"!()?x{201C}
的正面回溯。x{201C}
是左双引号(Unicode 双字节字符)。
u
- 允许 UTF-8 字符的修饰符,如 x{201C}
在您的原始正则表达式中,末尾的(?=[^ ])
是多余的,所以我删除了它。它本可以写成相同的(?!s)
,对单个空格字符的负面展望。
因此,您可以使用以下preg_split()
:
$return = preg_split('/s|(?<=w)(?=[.,:;!?)])|(?<=[.,"!()?x{201C}])/u', $text, -1, PREG_SPLIT_NO_EMPTY)
你可以试试这个:
preg_split('/[^PP.-]|(?<=s)-(?=s)|s+|.(?!d)/u', $str, null, PREG_SPLIT_NO_EMPTY);