【问题标题】:Sanitizing sentence in PHP with preg_replace使用 preg_replace 清理 PHP 中的句子
【发布时间】:2014-11-14 15:34:53
【问题描述】:

这是我当前的句子清理功能:

# sanitize sentence
function sanitize_sentence($string) {
    $string = preg_replace("/(?<!\d)[.,!?](?!\d)/", '$0 ', $string); # word,word. > word, word.
    $string = preg_replace("/(^\s+)|(\s+$)/us", "", preg_replace('!\s+!', ' ', $string)); # " hello    hello " > "hello hello"
    return $string;
}

用这个字符串运行一些测试:

$string = '     Helloooooo my frieeend!!!What are you doing??    Tell me what you like...........,please. ';

结果是:

echo sanitize_sentence($string);  
Helloooooo my frieeend! ! ! What are you doing? ? Tell me what you like. . . . . . . . . . . , please.

如您所见,我已经设法解决了一些要求,但我仍然坚持一些细节。最终结果应该是

Helloo my frieend! What are you doing? Tell me what you like..., please.

这意味着应该满足所有这些要求:

  1. .... 只能有一个或三个连续句点
  2. 只能有一个连续的逗号 ,
  3. 只能有一个连续的问号
  4. 只能有一个连续的感叹号
  5. 一个字母在一个单词中不能重复超过 2 次。例如:ma​​ss(正确)、ma​​ss(错误,应转换为ma​​ss
  6. 应始终在这些字符 .,!? 之后添加一个空格 这已经可以正常工作了!
  7. 在连续 3 个句点的情况下,仅在最后一个句点之后添加空格。
  8. 多余的空格(多于一个空格)应从句子的两端删除和修剪。 这已经很好了!

【问题讨论】:

  • 那么你的问题是什么?
  • 所以你使用这些规则的结果将如下:Helloo my frieend! What are you doing? Tell me what you like..., please.
  • @RichardBernards 是(修复了最后的字符串)。它不能是防弹的,所以最后的字符串会有 helloo 和 frieend
  • 这似乎是一组比通过正则表达式强制执行要复杂得多的要求。几乎听起来你需要为这样的事情构建自己的解析器。
  • @MikeBrant 据我了解,可以通过传递给 preg_replace() 函数的分隔规则数组来完成。

标签: php regex string preg-replace sanitize


【解决方案1】:

我认为正则表达式是一种非常合适的技术。毕竟是消毒。不是语法或语法更正。

function sanitize_sentence($i) {

    $o = $i;

    //  There can be only one or three consecutive periods . or ...
    $o = preg_replace('/\.{4,}/','… ',$o);
    $o = preg_replace('/\.{2}/','. ',$o);

    //  There can be only one consecutive ","
    $o = preg_replace('/,+/',', ',$o);

    //  There can be only one consecutive "!"
    $o = preg_replace('/\!+/','! ',$o);

    //  There can be only one consecutive "?"
    $o = preg_replace('/\?+/','? ',$o);  

    //  we just preemptively added a bunch of spaces.
    //  Let's remove any spaces between punctuation marks we may have added
    $o = preg_replace('/([^\s\w])\s+([^\s\w])/', '$1$2', $o);

    //  A letter cannot repeat itself more than 2 times in a word
    $o = preg_replace('/(\w)\1{2,}/','$1$1',$o);

    //  Extra spaces should be eliminated
    $o = preg_replace('/\s+/', ' ', $o);
    $o = trim($o);

    // we want three literal periods, not an ellipsis char
    $o = str_replace('…','...',$o);

    return $o;
}

【讨论】:

  • 您可能想检查一下 ',!?'在搜索中它们后面没有空格,所以它用那个单数空格替换它: preg_replace('/,+ */',', ',$o)
  • 请注意,此脚本将 3 个或更多句点转换为 ellipsis character,而不是 3 个句点。如果您想将它们保留为句点,则需要稍微重构
  • @OnlineCop 是为了满足 OP 要求 #6。我的代码包含一个试图纠正标点符号之间任何不需要的空格的子句
  • @sean9999 我注意到,我正在尝试调整它以将省略号转换为三个句点。除了那个问题,这看起来像是可行的答案。也许在最后将省略号替换为 3 个句点?
  • 是的!听起来像这样:) 我会更新代码
【解决方案2】:

我想我会一次一个地回答这些问题,因为一次专注于一项任务而不是把它们全部混在一起更有意义。

对于#5,我建议将([a-z])(\1{0,1})\1* 替换为$1$2,如in this example 所示。

它接受输入

     Helloooooo my frieeend!!!What are you doing??    Tell me what you like...........,please. 

并产生输出

     Helloo my frieend!!!What are you doing??    Tell me what you like...........,please. 

【讨论】:

  • 有趣的是,它适用于 regex101 网站,但不适用于我的 php 5.4.4 apache 服务器 - 出于某种原因,它无法识别 g 修饰符,这也是不适用于php.net/manual/es/reference.pcre.pattern.modifiers.php
  • 'g' 修饰符只为 preg_replace 添加了一个额外的字段:从 'preg_replace(...)' 到 'preg_replace(..., 1)'。在regex101站点,点击左侧“代码生成器”,查看代码差异。
【解决方案3】:

对于 #1(....),(?&lt;!\.)(\.{3}|\.)\.*\s* 可以替换为 $1(注意尾随空格),如 @987654321 所示@。

这需要

     Helloooooo my frieeend!!!What are you doing??    Tell me what you like...........,please. 

并产生输出

     Helloooooo my frieeend!!!What are you doing??    Tell me what you like... ,please. 

如您所见,您会得到一个时髦的... , 字符,这是您可能需要检查的另一件事。您可以在执行此清理之前检查 ., 的出现情况,或者在之后检查 . ,(之间的空格),除非您希望使用其他规则来删除多个标点符号。

为此从 regex101.com 网站生成的代码如下:

$re = "/(?<!\\.)(\\.{3}|\\.)\\.*\\s*/"; 
$str = "     Helloooooo my frieeend!!!What are you doing??    Tell me what you like...........,please. "; 
$subst = "$1 "; 
$result = preg_replace($re, $subst, $str);

【讨论】:

    【解决方案4】:

    对于#2、#3 和#4,您可以搜索([,?!])\1+\s* 并替换为$1(注意后面的空格),如this example

    这需要

         Helloooooo my frieeend!!!What are you doing??    Tell me what you like...........,please. 
    

    并产生

         Helloooooo my frieeend! What are you doing? Tell me what you like...........,please. 
    

    生成的代码如下所示:

    $re = "/([,?!])\\1+\\s*/"; 
    $str = "     Helloooooo my frieeend!!!What are you doing??    Tell me what you like...........,please. "; 
    $subst = "$1 "; 
    $result = preg_replace($re, $subst, $str);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-10
      • 1970-01-01
      • 1970-01-01
      • 2012-12-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多