优化“标记”正则表达式

时间:2010-07-07 20:53:37

标签: php regex

我目前使用这段代码通过删除/替换无效字符将给定文本缩减为有效的“标记”格式(仅限小写,a-z和减号)

        $zip_filename = strtolower($original);
        $zip_filename = preg_replace("/[^a-zA-Z\-]/g", '-', $zip_filename); //replace invalid chars
        $zip_filename = preg_replace("/-+/g", '-', $zip_filename); // reduce consecutive minus to only one
        $zip_filename = preg_replace("/^-/g", '', $zip_filename); // removing leading minus
        $zip_filename = preg_replace("/-$/g", '', $zip_filename); // remove trailing minus

关于如何将至少正则表达式放到一个正则表达式的任何提示?

感谢您的任何建议!

3 个答案:

答案 0 :(得分:3)

$zip_filename = trim(preg_replace("/[^a-z]+/", '-', $zip_filename),'-');

说明:

  1. A-Z没用,因为它应该是小写
  2. 在右括号后添加+将替换一个或多个连续的无效字符
  3. trim与第二个参数一起使用 - 用于修剪表格开头和结尾的字符将加快代码
  4. \-删除preg_replace也会在无效字符/多个连续连字符之间使用连字符,将其替换为单个连字符。

答案 1 :(得分:0)

这应该大大简化它......

$zip_filename = trim(strtolower($original));
$zip_filename = preg_replace("/\s\s+|--+|[^a-zA-Z-]/g", '-', $zip_filename);

trim将处理字符串之前和之后的空格。另请注意\s\s+--+。这些在查找重复项方面更有效。如果连续有2个或更多,它们匹配这些字符,从而避免不必要的替换操作。

但从技术上讲,它仍然可能有前导或尾随破折号。为此,你仍然需要这个......

$zip_filename = preg_replace("/^-|-$/g", '', $zip_filename);

(由于您使用的是另一个替换字符串,因此最后一个操作无法真正与其他操作组合。)

答案 2 :(得分:0)

通过将这四个操作合并为一个,您只会使代码更难以理解/维护。

您也不需要基于正则表达式的操作的复杂性和性能,以实现您的需要。

通过对str_replace进行循环调用,可以更轻松地实现双减号的减少:

while (substr_count($zip_filename, '--')) {
    $zip_filename = str_replace('--', '-', $zip_filename);
}

在一个命名良好的类方法中包含它将抽象出任何明显的复杂性并有助于代码的可读性。

最后两个操作可由trim()函数处理:

$zip_filename = trim($zip_filename, '-');

然后,您可以将基于正则表达式的操作替换为较少cpu攻击性的东西,并且可以让其他人更容易理解:

//replace invalid chars
$zip_filename = preg_replace("/[^a-zA-Z\-]/g", '-', strtolower($original)); 

// reduce consecutive minus to only one
while (substr_count($zip_filename, '--')) {
    $zip_filename = str_replace('--', '-', $zip_filename);
}

// remove leading and trailing minus
$zip_filename = trim($zip_filename, '-');