简体   繁体   English

PHP正则表达式用于特定的文本模式

[英]PHP regex for a specific pattern of text

On my website I've inserted the year a project was created in the body and swapping that out with "six years ago" (or however long it was). 在我的网站上,我插入了当年在主体中创建一个项目的年份,并将其替换为“六年前”(或时间长短)。

So in my content I have: 所以在我的内容中,我有:

We've been in business since 1998 and produced this packaging design [2011] years ago. 我们从1998年开始从事业务,并于[2011年]之前制作了这种包装设计。

I'm trying to use regex to put 2011 into a variable to later search and replace, and can't figure it out. 我正在尝试使用正则表达式将2011年放入变量中,以便稍后进行搜索和替换,但无法弄清楚。 There's only going to be one instance per page. 每页只有一个实例。 I'm fine with searching and replacing, it's just regex I've never been able to get my head around. 我可以进行搜索和替换,这只是正则表达式,我从来没有动过头。

To address comments below - the year is variable, that's why I'm wanting to use regex. 为了解决以下问题-年份是可变的,这就是为什么我要使用正则表达式。

example

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

or 要么

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

So I put the year held in braces into a variable with regex as $then, subtract that from the current year to make $age (which is converted into a word by another function) 因此,我将花括号中的年份放入正则表达式为$ then的变量中,然后从当前年份中减去该年份以得出$ age(由另一个函数转换为单词)

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

I've tried 我试过了

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

but it returns the first date — not the one in braces. 但它会返回第一个日期,而不是大括号中的那个。

Use function preg_replace_callback() : 使用函数preg_replace_callback()

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

demo 演示

If this was my project, I'd probably go with a preg_replace_callback() call leveraging a lookup array of words, and a fallback replacement when the bracketed date was "out of range". 如果这是我的项目,那么我可能会利用一个查找字词数组进行preg_replace_callback()调用,并在括号中的日期“超出范围”时进行后备替换。

*It is important that you are pluralizing year when appropriate. *请务必在适当的时候将year复数。
*The second ] in my pattern doesn't need escaping, but you may add it if you you feel it improves readability. *我模式中的第二个]不需要转义,但是如果您认为它可以提高可读性,则可以添加它。
*I am also matching years ago so that the replacement text makes sense in all cases; *我也在years ago匹配,因此替换文字在所有情况下都有意义; you may like to remove this trailing text in the original input text. 您可能希望在原始输入文本中删除此尾随文本。

Code: ( 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;

Output: 输出:

<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>

Assuming this format [2002] years , as an alternative to you might use this regex: 假设此格式为[2002] years ,则可以使用此正则表达式作为替代方法:

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

Explanation 说明

\[      # Match [
(       # Capturing group
  \d{4} # Match 4 digits
)       # Close capturing group
\]      # Match ]
 years  # Match `whitespace`years

Then you could use preg_match to match the year in group 1, calculate the difference in years and perform formatting for singular or plural. 然后,您可以使用preg_match来匹配组1中的年份,以年为单位计算差异,并执行单数或复数格式。

For example: 例如:

$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 演示php输出

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM