我需要通过空格,标点符号,换行符将文本分成数组。以下是示例文本:
男士夹克是绿色的。 他 - 现代历史上最大的明星 - 骑自行车的速度非常快(每小时230公里)。这怎么可能?!他用的是什么样的自行车? 他的自行车的半自动装备相当昂贵,显着有助于达到这个速度。一些(或许可能很多)声称他是世界上最快的! “我看到他骑自行车!”约翰迪尔先生说。 “他设定的速度是每小时133.78公里,”听起来令人难以置信;听起来很有欺骗性。
我已经获得了regex that does that:
preg_split('/(?<=\s)|(?<=\w)(?=[.,:;!?()-])|(?<=[.,!()?\x{201C}])(?=[^ ])/u', $text);
但是目前它将以下semi-automatic
分成两个单词,而它必须保持为一个单词。如果除了semi - automatic
之外还有空格,那么这应该是三个单词。我不太明白这个正则表达式是如何工作的,所以感谢任何帮助。
第二个问题是,如果文本包含换行符,它会捕获换行符,但也会创建冗余元素。参见example - 元素[8]和[9]。元素[8]是多余的。我该如何解决它?
答案 0 :(得分:1)
我没有测试以下内容。
首先让我们改变正则表达式:
/[.,:;!?()\s]|(?<=\s)-(?=\s)/u
说明:
[.,:;!?()\s]
- 在标点符号上拆分
|(?<=\s)-(?=\s)
- (替代)拆分-
-
接下来,对结果执行array_filter()
,删除空| false元素
编辑:
要使用标点符号:
/(?=[.,:;!?()\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
注意:lookarounds只匹配某些内容,它们消耗零个字符,因此您可能遇到“零宽度断言”术语。如果我们没有使用lookarounds,则正则表达式引擎将匹配该字符并将其从匹配项中删除。管道元字符|
是OR
,正则表达式为alternate
模式。
\s
- 匹配空格字符。我们不需要这样做,因为我们想要删除它。
(?<=\w)(?=[.,:;!?)])
- 或者匹配单词字符\w
的正向lookbehind,然后是以下任何标点符号.,:;!?)
的正向前瞻。
(?<=[.,"!()?\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)
答案 1 :(得分:0)
你可以试试这个:
preg_split('/[^\PP.-]|(?<=\s)-(?=\s)|\s+|\.(?!\d)/u', $str, null, PREG_SPLIT_NO_EMPTY);