【问题标题】:PHP preg_replace, split or match?PHP preg_replace,拆分还是匹配?
【发布时间】:2013-11-05 09:00:08
【问题描述】:

我需要解析一个字符串并为不符合我的媒体播放器队列的正常格式的电视节目名称替换特定格式。

一些例子

Show.Name.2x01.HDTV.x264 应该是 Show.Name.S02E01.HDTV.x264
Show.Name.10x05.HDTV.XviD 应该是 Show.Name.S10E05.HDTV.XviD

在节目名称之后,x 之前可能有 1 或 2 位数字,我希望输出始终是带两位数字的 S,因此如果需要,请添加前导零。在 x 之后,它应该始终是带有两位数的 E。

我浏览了 preg_replace、split 和 match 函数的手册页,但不太清楚我应该在这里做什么。我可以将我想要的字符串部分与/\dx\d{2}/ 匹配,所以我想首先检查字符串是否具有该模式,然后尝试找出如何将这些部分从匹配中拆分出来,但我没有得到任何结果。

我最擅长使用示例,因此,如果您能用示例为我指明正确的方向,那就太好了。我现在唯一的测试区域是 PHP 4 安装,所以请不要指定 PHP 5 的具体说明,一旦我了解发生了什么,我可能会在以后为 PHP 5 更新它(如果需要):)

【问题讨论】:

  • please no PHP 5 specific directions -- 为什么不呢?为什么要使用古老的 PHP 版本?为什么不想升级到更新的版本?
  • 我的媒体服务器运行它自己的 php4 后端,我现在不想乱用它。这是另一个问题=/
  • 你试过什么?请给我们看一些代码。没有人会安装 PHP 4 并为您完成工作。
  • 我不会要求任何人这样做,提供的各种代码示例似乎都可以达到目标,所以这正是我所要求的。

标签: php regex preg-replace preg-match preg-split


【解决方案1】:

使用 PHP4 及以下版本使用#sprintf 作为解决方案的不同方法。

$text = preg_replace('/([0-9]{1,2})x([0-9]{2})/ie',
                     'sprintf("S%02dE%02d", $1, $2)', $text);

注意:自 PHP5.5 起,e 修饰符的使用已被弃用,因此请使用 preg_replace_callback()

$text = preg_replace_callback('/([0-9]{1,2})x([0-9]{2})/', 
      function($m) {
         return sprintf("S%02dE%02d", $m[1], $m[2]);
      }, $text);

输出

Show.Name.S02E01.HDTV.x264
Show.Name.S10E05.HDTV.XviD

working demo

【讨论】:

【解决方案2】:

preg_replace 是你正在寻找的函数。

您必须编写一个选择正确位置的正则表达式模式。

  <?php
  $replaced_data = preg_replace("~([0-9]{2})x([0-9]{2})~s", "S$1E$2", $data);
  $replaced_data = preg_replace("~S([1-9]{1})E~s", "S0$1E", $replaced_data);
  ?>

抱歉,我无法测试它,但它应该可以工作。

【讨论】:

  • 您的正则表达式中没有字母,因此不需要i 修饰符。您也不要在正则表达式中使用任何 . 元字符,这意味着也不需要 s 修饰符。此外,替换不处理前导0s,提问者明确表示他们希望看到。
  • 我修改了模式。
  • 你为什么使用s修饰符?!仅当您使用 . 元字符时,它才有效。你不要在你的正则表达式中使用它。它不是必需的。此外,[1-9]{1}[1-9]完全相同。没有必要明确说某物只有其中之一;这是暗示的。
  • @SverriM.Olsen:你忘记了x这封信。
  • @CasimiretHippolyte 是的,我错过了。不过,使用 [xX] 就足够了。但是,我从未在电视节目文件名的剧集/季部分中看到大写 X,但为了安全起见,它们可能会出现得更好。
【解决方案3】:

使用preg_replace_callback()函数的另一种方式:

$subject = <<<'LOD'
Show.Name.2x01.HDTV.x264 should be Show.Name.S02E01.HDTV.x264
Show.Name.10x05.HDTV.XviD should be Show.Name.S10E05.HDTV.XviD
LOD;

$pattern = '~([0-9]++)x([0-9]++)~i';
$callback = function ($match) {
    return sprintf("S%02sE%02s", $match[1], $match[2]);
};

$result = preg_replace_callback($pattern, $callback, $subject);

print_r($result);

【讨论】:

  • 谢谢我以前没有见过这个功能,绝对值得进一步研究:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-06
  • 2016-09-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多