处理一些文本格式和分析 - 我有一大块文本,我试图分成单个句子。显然,explode
可以使用每个句子末尾的标点符号来轻松完成。
我遇到的问题是,普通语言还包含不表示句子结尾的句点 - 例如小数和缩写。例如,“一支团队预计他们将打破以前创纪录的92.49%的效率,这是1991年制定的。”将导致两个句子,第二个句子以“49%”开头。这就是我要避免的。
我可以安全地删除这些句子中期而不影响我的分析,但我需要保持每个字符串的其余部分完整 - 这就是我遇到麻烦的地方。在上面小数点的情况下,我可以将字符与$str = preg_replace("/[\.]+[0-9]/", "", $str);
匹配 - 但是替换匹配也会消除该数字的第一个小数。
如何使用preg_replace
并保持某些字符完好无损?
更新
一些答案建议使用前瞻来匹配角色而不将其包含在替换中。虽然这适用于上面给出的例子,但这不适用于缩写(例如美国) - 是否有更普遍的情况我们可以提出,或者至少可能是对应的“看后”?
答案 0 :(得分:0)
如果你调整你的正则表达式以匹配数字围绕小数的位置怎么办...这样的话可能
/[0-9]+[\.][0-9]+/
修改强>
匹配然后替换?
preg_match_all("/[0-9]+[\.][0-9]+/", $str, $out, PREG_PATTERN_ORDER);
然后遍历$ out数组并对这些字符串执行替换以删除小数。
答案 1 :(得分:0)
我认为这应该适合你:
[\.](?=[0-9])
它使用前瞻来匹配小数后跟0-9,但不包括匹配中的0-9。
更新:
我考虑到您的更新后又看了一眼,但我无法想到解决所有用例的解决方案。我能够提出一个更为通用的解决方案来覆盖更多情况:
[\.](?=[^\s])
这会查找一个句点或小数点后跟任何不是空格,制表符,换行符等的字符,而不是后面跟一个数字。这有助于捕捉可能导致问题的更多事情,但它仍然遗漏了很多。
这适用于以下内容:
“一支团队预计他们将打破以前创纪录的92.49%的效率,这是1991年在美国设定的。”
但是会因为这样的事情而失败:
“一支团队预计他们将打破以前创纪录的92.49%效率,这是1991年在美国设定的。”
正如@vrijdenker所提到的,名字将是另一个问题。我只是不知道你如何区分一个句子结尾的句号和一个缩写的中间名词之后的句号。
答案 2 :(得分:0)
尝试:
$str = preg_replace("/\.(?=\d)/", "", $str);
答案 3 :(得分:0)
由于您不想只忽略属于某个数字的点,还要忽略缩写,名称等,只需暂时忘记这些数字。
我已经设置了一个包含一些Lorem Ipsum的小提琴,在中间我添加了你的例句,后面加了一些缩写和一个名字。
<?php
$var = <<<EOT
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam tortor velit, facilisis ac malesuada vel, tristique sit amet purus.
Donec magna turpis, iaculis vitae nisl et, porttitor tincidunt augue. Fusce odio tortor, laoreet ut turpis eget, lobortis ultrices lorem.
One team anticipates they will break the previous record of 92.49% efficiency, which was set in 1991. B.T.W.: abbreviations like U.S. and names like I.M. Theman should also be ignored.
Duis lobortis lacus ligula, a lobortis ipsum lacinia in. Suspendisse potenti. Donec mattis volutpat nisi, non cursus est. Nam pellentesque congue lectus, in auctor erat viverra sit amet.
Mauris pellentesque magna dolor, in euismod neque mattis eu. Etiam in massa eget eros consectetur iaculis eu in tortor.
Mauris luctus, nulla ac blandit molestie, augue dui iaculis orci, eu suscipit ipsum mauris a enim. Curabitur vel mauris lorem. Maecenas et metus cursus, posuere nisi vitae, auctor turpi.
EOT;
$var = preg_replace('/[^\.]{2,}\.\s/', '$0[[SPLIT]]', $var);
$lines = explode('[[SPLIT]]', $var);
print_r($lines);
如果查看文本,可以构成以下逻辑:
这个逻辑允许以下正则表达式:
/[^\.]{2,}\.\s/
正如您在此处所见,这有效:http://ideone.com/MkyEcL
请注意以下事项:
另请注意,我可以想到我认为你无法捕获的案例。例如,以下句子:
“我是Theman先生,我喜欢StackOverflow。”
在这种情况下,缩写有多个字符,后跟空格,甚至是点后的字符,空格是大写字符。我认为在正则表达式中捕获此类案例根本不可能,因为您只需要知道它是否是缩写。
答案 4 :(得分:-1)
尝试$str = preg_replace("/[\.](+[0-9])/", "$1", $str);