【问题标题】:RegEx to exclude number using PHP正则表达式使用 PHP 排除数字
【发布时间】:2013-05-02 01:47:33
【问题描述】:

这个问题是我之前问题的延续:

RegEx to exclude academic title

我想使用带有字符点 (.) 的正则表达式将段落字符串拆分为句子数组。下一个问题是关于数字的。

这是一个例子:

2013 年。您好,安德烈先生,您的钱是 40.000 印尼盾。

当然是正确的输出:

Array ( [0] => 今年 2013 [1] => 你好 Andre 先生,你的钱是 40.000 印尼盾)

标题问题(先生)已经从我之前的问题中解决了。我试过添加数字的正则表达式,但仍然不起作用。

我没用的代码:

$titles_number=array('(^[0-9]*)','(?<!Mr)', '(?<!Mrs)', '(?<!Ms)');
$sentences=preg_split('/('.implode('',$titles_number).')\./',$text);
print_r($sentences);

我可以一击完成吗(一个正则表达式可以解决两个问题)?如果我做不到,请告诉我。 提前致谢

【问题讨论】:

  • 您是否尝试过使用构建块 (?&lt;!\d) (?!\d) 进行负前瞻并在后面查找数字?
  • 虽然我没有答案,但网站 www.regexpal.com 是测试正则表达式的好方法。它是基于 JavaScript 的,因此它会实时更新。我经常使用它。
  • 感谢您的评论,仍在尝试。 regex101.com 也值得一试:D

标签: php regex string


【解决方案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...
  • (?&lt;=Prof\.|Dr\.|Mr\.|Mrs\.|Ms\.) ...这是敬语的一部分...
  • (?=\d) ...或数字的一部分

注释:

  1. (?&lt;=Prof\.|Dr\.|Mr\.|Mrs\.|Ms\.) 是合法的,因为交替位于顶层。也就是说,它就像几个离散的后视,每个都有固定的长度。这就是为什么我不得不在每个分支中重复 \. 而不是使用 (?&lt;=(?:Prof|Dr|Mr|Mrs|Ms)\.)

  2. \.(?=\d) 似乎足以识别作为数字一部分的点。如果确实需要检查点前后的数字,可以使用(?=(?&lt;=\d\.)\d)

  3. 如果这是针对比作业问题更严重的问题,您应该放弃正则表达式并寻找自然语言处理库。尽管这一切都很粗糙,但它非常接近正则表达式所能做的极限。

【讨论】:

  • 哇,这是完整的答案,也摆脱了拼写错误的问题,谢谢大师..:D
【解决方案2】:

如果您注意到句子末尾的每个点后跟空格/制表符/换行符或字符串末尾,则可以避免数字问题(可能还有其他问题):

$titles=array('(?<!Mr)', '(?<!Mrs)', '(?<!Ms)');
$sentences=preg_split('/('.implode('',$titles).')\.(?=\s|$)/',$text);
print_r($sentences);

【讨论】:

  • 哇,好主意。但是当出现这样的错字问题时,这是行不通的:“今年 2013 年。你好,安德烈先生,你的钱是 40.000 卢比。”总的来说,谢谢你的回答:D
猜你喜欢
  • 1970-01-01
  • 2022-07-22
  • 2021-09-16
  • 1970-01-01
  • 1970-01-01
  • 2014-04-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多