【问题标题】:Simplify RegEx: Avoid both test and replace简化正则表达式:避免测试和替换
【发布时间】:2017-03-14 15:36:55
【问题描述】:

我需要一个 PHP 和 JavaScript 中的函数,为标题添加带括号的年份。但如果标题包含带括号的单词,年份和单词应该共用括号,用“/”分隔。

foo("Ferrari (ABC)", 2016); // Ferrari (2016/ABC)
foo("Ferrari", 1979);       // Ferrari (1979)
foo("X(Y)Z (PQR)", 1987);   // X(Y)Z (1987/PQR)

目前,我检查模式,如果匹配则替换,如果不匹配则执行其他操作。可以将此功能简化为更简单(最好是单个)的操作吗?请提供一个完整的例子。

PHP:

function foo($title, $year) {
  $pattern = "/(\()([A-Z]+\))$/";
  if(preg_match($pattern, $title))
    $title = preg_replace($pattern, "${1}".$year."/${2}", $title);
  else
    $title = "$title ($year)";
}

JavaScript:

function foo(title, year) {
  var pattern = /(\()([A-Z]+\))$/;
  if(pattern.test(title))
    title = title.replace(pattern, "$1"+year+"/$2");
  else
    title = title + " (" + year + ")";
}

【问题讨论】:

  • 使用indexOf('(')?
  • 您在寻找速度吗?还是您正在寻找更少字节的代码?
  • 更少的代码字节。或者主要是为了摆脱 if/else。但不以过于复杂的 RegEx 为代价。只是如果我想念一种简单而出色的方法。

标签: javascript php regex


【解决方案1】:

可以说,使用替换会更容易一些。

PHP

<?php

function foo($title, $year) {
    if (substr($title,-1) == ")") {
        return str_replace(")","/".$year.")",$title);
    } else {
        return $title . " (" . $year . ")";
    }
}

echo foo("My Title (ABC)", 1996);
echo "<br />";
echo foo("My Title", 1996);

?>

JavaScript

function foo(title, year) {
	if (title.charAt(title.length - 1) == ")")
		return title.replace(")",  "/" + year + ")");
	else
		return title + " (" + year + ")";
}

console.log(foo("My Title (ABC)",1996));
console.log(foo("My Title",1996));

【讨论】:

  • 这是不正确的。年份应该在这个词之前出现。除此之外,这是一个很好的简化,但是,我希望有一种不涉及 if/else 的方法。
【解决方案2】:

是的,有一个更简单的方法。

1- 检查 $title 中是否有括号。
如果为真,只需使用函数str_replace 进行简单的搜索/替换。搜索 "(" 替换为 "($yaer/"
这只会将年份和斜线添加到您已经准备好的字符串中。

2- 如果你没有括号,那么只需$title = "$title ($year)";

function foo($title, $year) {
 if ( strpos($title,"(") > 1 )
   $title = str_replace("(","($year/",$title);
 else
   $title = "$title ($year)";
}

同样的逻辑也适用于 Javascript

【讨论】:

  • 标题的主要部分也可以包含括号,因此只应修改包含单个大写单词的尾括号。
【解决方案3】:

在 Javascript 中使用 RegExp 的示例:

  function foo(str, year) {
    var re = /(\(([A-Z]+)\))?$/
    return str.replace(re, function(b, b, found) {
      if (found) 
        return '(' + year + '/' + found + ')';
      else 
        return ' ' + year;
    })
  }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-11
    • 1970-01-01
    • 2014-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多