【问题标题】:trim lines and shrink whitespaces using regex for multi line string使用正则表达式修剪多行字符串并缩小空格
【发布时间】:2017-06-22 02:00:20
【问题描述】:

正在使用php function想要创建一个函数来修剪多行字符串中所有不必要的空格。

它不起作用的正则表达式是在末尾删除空格的正则表达式:

// Always trim at the end. Warning: this seems to be the costlier
// operation, perhaps because looking ahead is harder?
$patterns[] = ['/ +$/m', ''];

给定来自文本区域的以下字符串:

 first  line... abc   //<-- blank space here
 second  is  here... def   //<-- blank space here
 //<-- blank space here
 fourth  line... hi  there   //<-- blank space here

 sith  is  here....   //<-- blank space here

每行的开头和结尾有空格,单词之间有多个空格。

运行函数后:

$functions->trimWhitespace($description, ['blankLines' => false]);

这是我得到的:

first line... abc //<-- blank space here
second is here... def //<-- blank space here
//<-- no bank space here
fourth line... hi there //<-- blank space here

sith is here....//<-- no blank space here

为什么只删除最后一行的尾随空格?

【问题讨论】:

  • 如果不确定使用的换行符类型,请尝试'/ +\r?$/m'
  • 既然是PHP,为什么不用'/\h+$/um'
  • @bobblebubble 耶!这就是它所缺少的。我目前在 Linux 中,不确定它是否适用于 Windows 和 Mac。请把解决方案放在答案中。谢谢。
  • @WiktorStribiżew 我已经尝试过那个,但它没有用。我花了几个小时试图找到解决方案。
  • 这是否意味着如果 CR 符号存在,您也想删除它?我建议'/\h+(?=\r?$)/um'

标签: php regex pcre multiline


【解决方案1】:

preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &amp;$count ]] )

所以你想要preg_replace('/[\s]+$/m', '', $string)

【讨论】:

    【解决方案2】:

    使用两步法:

    <?php
    
    $text = " first  line... abc   
     second  is  here... def   
      <-- blank space here
     fourth  line... hi  there   
    
     sith  is  here....   ";
    
    // get rid of spaces at the beginning and end of line
    $regex = '~^\ +|\ +$~m';
    $text = preg_replace($regex, '', $text);
    
     // get rid of more than two consecutive spaces
    $regex = '~\ {2,}~';
    $text = preg_replace($regex, ' ', $text);
    echo $text;
    
    ?>
    

    a demo on ideone.com

    【讨论】:

    • +1 用于完整(两步)方法,但它并没有完全满足我的要求。我仍然在行尾得到 1 个空格(不是最后一个)。但是添加 \ +\r?$~m 确实有效。
    【解决方案3】:
     preg_replace('/*(.*) +?\n*$/', $content)
    

    Live Demo

    【讨论】:

      【解决方案4】:

      您需要/gm 而不仅仅是/m

      代码应该变成: (这段代码不行,更新一下就行了)

      $patterns[] = ['/ +$/mg', ''];
      

      这里的工作示例:https://regex101.com/r/z3pDre/1

      更新:

      g 标识符,不要这样工作。我们需要用preg_match_all替换preg_match

      使用不带g 的正则表达式,如下所示:

      $patterns[] = ['/ +$/m', ''];
      

      【讨论】:

      • 我收到了这个警告Unknown modifier 'g'
      • @ChazyChaz 尝试“mg”(不是 gm)
      • 我正在使用'/ +$/mg'
      • 使用 preg_match_all 不加“g”,更新答案
      • 我不想验证,我想从前导/尾随/不必要的空格中清除字符串。
      【解决方案5】:

      您可以使用 (*ANYCRLF) 动词重新定义 $ 匹配的位置。

      见下面PHP demo

      $s = " ddd    \r\n  bbb     ";
      $n = preg_replace('~(*ANYCRLF)\h+$~m', '', $s); // if the string can contain Unicode chars,
      echo $n;                                        // also add "u" modifier ('~(*ANYCRLF)\h+$~um')
      

      详情

      • (*ANYCRLF) - 指定换行约定:(*CR)(*LF)(*CRLF)
      • \h+ - 1+ 水平空格字符
      • $ - 行尾(现在,在 CR 或 LF 之前)
      • ~m - 开启多行模式($ 匹配行尾)。

      如果您想让$ 匹配任何Unicode 换行符,请将(*ANYCRLF) 替换为(*ANY)

      PCRE reference中的Newline conventions

      (*CR)        carriage return
      (*LF)        linefeed
      (*CRLF)      carriage return, followed by linefeed
      (*ANYCRLF)   any of the three above
      (*ANY)       all Unicode newline sequences
      

      现在,如果你需要

      • 从头到尾修剪线条
      • 将行内的空格缩小为一个空格

      使用

      $s = " Ł    ę  d    \r\n  Я      ёb     ";
      $n = preg_replace('~(*ANYCRLF)^\h+|\h+$|(\h){2,}~um', '$1', $s);
      echo $n;
      

      请参阅PHP demo

      【讨论】:

      • @ChazyChaz 读取您的输入是 utf-8 并且首选空替换我投票支持 Wiktors 解决方案。也许你想添加u 标志(这里可能不需要)。
      • 嗯,我的php输出是utf-8,输入是默认的。我已经使用该标志来验证(preg_match)。这更详细,但我想要一个完整的方法(不仅仅是尾随),就像 Jan 的回答一样,因为我不会使用我找到的函数(我更喜欢更简单的东西)。
      • 什么是“完整”方法?从两端修剪线条并将所有 2+ 空格缩小为 1?
      • 有什么方法可以将此正则表达式与修剪前导空格的正则表达式结合起来?通常,换行符在一个点之后,所以我更喜欢使用ANYCRLF 以获得所有操作系统的最大兼容性。
      • 是的,基本上就是这样,我不认为有更多的地方可以堆叠空间。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-13
      • 2023-03-31
      • 2011-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多