我没有测试以下内容。
首先让我们更改正则表达式:
/[.,:;!?()\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}])(?=[^ ])
解释:
哦,我的,我的头今天不在比赛中。您的正则表达式几乎就在那里,只需要一两个 mod,所以这是最终的正则表达式。
/\s|(?<=\w)(?=[.,:;!?)])|(?<=[.,"!()?\x{201C}])/u
注意:环视只是匹配某些东西,它们消耗零个字符,因此您可能会遇到“零宽度断言”术语。如果我们不使用环视,正则表达式引擎将匹配该字符并将其从匹配中删除。管道元字符|是一个OR,在正则表达式中是一个alternate模式。
\s- 匹配一个空白字符。我们不需要在环顾中使用它,因为无论如何我们都想删除它。
(?<=\w)(?=[.,:;!?)])-OR 匹配一个单词字符的正向lookbehind,\w后跟任何以下标点字符的正向lookahead .,:;!?)。
(?<=[.,"!()?\x{201C}])- 或匹配以下标点字符的正向后视.,"!()?\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)