这个问题是我上一个问题的延续:
我希望使用带有字符点(。)的正则表达式将段落字符串拆分为句子数组。接下来的问题是数字。
以下是一个例子:
在2013年。安德烈先生,你好,你的钱是Rp 40.000。
当然正确的输出:
数组([0] =>在今年2013年[1] =>你好安德烈先生,你的钱是 Rp 40.000)
标题问题(先生)已经从我之前的问题中解决了。我试过添加正则数字但仍然无效。
我的工作代码:
$titles_number=array('(^[0-9]*)','(?<!Mr)', '(?<!Mrs)', '(?<!Ms)');
$sentences=preg_split('/('.implode('',$titles_number).')\./',$text);
print_r($sentences);
我可以一击(一个正则表达式摆脱两个问题)吗?告诉我,如果我不能这样做。 提前致谢
答案 0 :(得分:1)
使用preg_match_all()
:
preg_match_all(
'/[^\s.][^.]*(?:\.(?:(?<=Prof\.|Dr\.|Mr\.|Mrs\.|Ms\.)|(?=\d))[^.]*)*\./',
$subject, $result, PREG_PATTERN_ORDER);
print_r($result[0]);
说明:
[^\s.]
匹配下一个非空白字符(即跳过句子之间的任何空格)[^.]*
吞噬任何非点字符\.
匹配点IF ... (?<=Prof\.|Dr\.|Mr\.|Mrs\.|Ms\.)
......这是尊敬的一部分...... (?=\d)
...或数字的一部分注释:
(?<=Prof\.|Dr\.|Mr\.|Mrs\.|Ms\.)
是合法的,因为更改位于顶层。也就是说,它就像几个独立的外观,每个都有固定的长度。这就是为什么我不得不在每个分支中重复\.
而不是使用(?<=(?:Prof|Dr|Mr|Mrs|Ms)\.)
。
\.(?=\d)
似乎足以识别一个数字的一部分。如果您确实需要检查点之前和之后的数字,则可以使用(?=(?<=\d\.)\d)
代替。
如果这是比家庭作业更严重的问题,你应该丢弃正则表达式并寻找自然语言处理库。粗俗就是这一切,它非常接近你可以用正则表达式做的极限。
答案 1 :(得分:0)
如果您注意到句子末尾的每个点后跟空格/制表符/换行符或字符串末尾,则可以避免数字问题(可能还有其他问题):
$titles=array('(?<!Mr)', '(?<!Mrs)', '(?<!Ms)');
$sentences=preg_split('/('.implode('',$titles).')\.(?=\s|$)/',$text);
print_r($sentences);