【问题标题】:PHP regex for a specific pattern of text特定文本模式的 PHP 正则表达式
【发布时间】:2018-02-11 03:10:40
【问题描述】:

在我的网站上,我在正文中插入了一个项目创建的年份,并将其替换为“六年前”(或者不管它有多长)。

所以在我的内容中我有:

我们从 1998 年开始营业,并在 [2011] 年前制作了这种包装设计。

我正在尝试使用正则表达式将 2011 放入变量中以供以后搜索和替换,但无法弄清楚。每页只有一个实例。我可以搜索和替换,这只是我一直无法理解的正则表达式。

为了解决下面的 cmets - 年份是可变的,这就是我想要使用正则表达式的原因。

例子

$bodycontent = <p>We've been in business since 1998 
and produced this logo design [2002] years ago.</p>

$bodycontent = <p>We've been in business since 1998 
and produced this website design [2016] years ago.</p>

所以我将大括号中的年份放入一个变量中,正则表达式为 $then,从当前年份中减去它,得到 $age(由另一个函数转换为单词)

$bodycontent = str_replace("[".$then."]",$age,$bodycontent)

我试过了

preg_match("[\d{4}]",$bodycontent,$found); 

但它返回第一个日期——而不是大括号中的日期。

【问题讨论】:

  • 你不需要正则表达式只需str_replace
  • 如果子字符串是可变的。 preg_replace_callback() 将作为一个电话进行。或者,如果年份的可能性有些有限,您可以str_replace() 使用一组查找和一组替换。请显示几个示例输入以显示可变性。您的编码尝试在哪里?

标签: php regex


【解决方案1】:

使用函数preg_replace_callback()

$bodycontent = preg_replace_callback('~\[(\d{4})\]~', function($match) {
    return (date('Y') - $match[1]) . " ago";
}, $bodycontent);

demo

【讨论】:

    【解决方案2】:

    如果这是我的项目,我可能会使用 preg_replace_callback() 调用,利用查找单词数组,并在括号中的日期“超出范围”时使用备用替换。

    *在适当的时候将year 复数很重要。
    *我的模式中的第二个] 不需要转义,但如果您觉得它提高了可读性,可以添加它。
    *我也匹配years ago,以便替换文本在所有情况下都有意义;您可能希望删除原始输入文本中的尾随文本。

    代码:(Demo)

    $bodycontent = "<p>We've been in business since 1998 and produced this logo design [1995] years ago.</p>\n";
    $bodycontent .= "<p>We've been in business since 1998 and produced this website design [2018] years ago.</p>\n";
    $bodycontent .= "<p>We've been in business since 1998 and produced this website design [2017] years ago.</p>\n";
    $bodycontent .= "<p>We've been in business since 1998 and produced this website design [2016] years ago.</p>";
    
    $lookup=['less than a','one','two','three','four','five','six','seven','eight','nine',
             'ten','eleven','twelve','thirteen','fourteen','fifteen','sixteen','seventeen','eighteen','nineteen'
    ];  // extend as needed
    
    $bodycontent = preg_replace_callback('/\[(\d{4})] years ago/', function($m)use($lookup){
        $diff=date('Y')-$m[1];
        if(isset($lookup[$diff])){
            return $lookup[$diff].' year'.($diff>1?'s':'').' ago';
        }else{
            return "in {$m[1]}";  // out of lookup range, use backup text
        }
    }, $bodycontent);
    
    echo $bodycontent;
    

    输出:

    <p>We've been in business since 1998 and produced this logo design in 1995.</p>
    <p>We've been in business since 1998 and produced this website design less than a year ago.</p>
    <p>We've been in business since 1998 and produced this website design one year ago.</p>
    <p>We've been in business since 1998 and produced this website design two years ago.</p>
    

    【讨论】:

      【解决方案3】:

      假设这种格式[2002] years,作为替代你可以使用这个正则表达式:

      \[(\d{4})\] years

      说明

      \[ # 匹配 [ ( # 捕获组 \d{4} # 匹配 4 个数字 ) # 关闭捕获组 \] # 匹配 ] years # 匹配 `whitespace`years

      然后您可以使用preg_match 匹配第 1 组中的年份,计算年份差并执行单数或复数格式。

      例如:

      $bodycontent = "<p>We've been in business since 1998 and produced this logo design [2002] years ago.</p>";
      
      preg_match('/\[(\d{4})\] years/', $bodycontent, $matches);
      $years = date('Y') - $matches[1];
      $result = sprintf("%s year%s",
          $years,
          $years === 1 ? "": "s"
          );
      $bodycontent =  str_replace($matches[0], $result, $bodycontent);
      

      Demo php output

      【讨论】:

        猜你喜欢
        • 2012-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多