正则表达式创建url友好字符串

时间:2014-03-25 05:22:05

标签: regex preg-replace

我想从用户输入创建一个url友好字符串(一个只包含字母,数字和连字符的字符串):

  1. 删除所有不是a-z,0-9,空格或连字符的字符
  2. 用连字符替换所有空格
  3. 用单个连字符替换多个连字符
  4. 预期产出:

    my project -> my-project 
    test    project -> test-project
    this is @ long str!ng with spaces and symbo!s -> this-is-long-strng-with-spaces-and-symbos
    

    目前我正在分三步执行此操作:

    $identifier = preg_replace('/[^a-zA-Z0-9\-\s]+/','',strtolower($project_name)); // remove all characters which are not a-z, 0-9, space or hyphens
    
    $identifier = preg_replace('/(\s)+/','-',strtolower($identifier)); // replace all spaces with hyphens
    
    $identifier = preg_replace('/(\-)+/','-',strtolower($identifier)); // replace all hyphens with single hyphen
    

    有没有办法用一个正则表达式做到这一点?

3 个答案:

答案 0 :(得分:1)

我认为没有一种方法可以做到这一点,但你可以减少替换次数,在极端情况下,使用像这样的单线:

$text=preg_replace("/[\s-]+/",'-',preg_replace("/[^a-zA-Z0-9\s-]+/",'',$text));

首先删除所有非字母数字/空格/破折号,然后用一个替换所有空格和多个破折号。

答案 1 :(得分:1)

是的,@ Jerry说你不能在一个替换中执行此操作,因为您尝试用两个不同的项(空格或破折号,取决于上下文)替换特定字符串。我认为Jerry的答案是解决这个问题的最好方法,但你能做的其他事情就是使用preg_replace_callback。这允许您根据匹配的内容评估表达式并对其进行操作。

$string = 'my project
test    project
this is @ long str!ng with spaces and symbo!s';

$string = preg_replace_callback('/([^A-Z0-9]+|\s+|-+)/i', function($m){$a = '';if(preg_match('/(\s+|-+)/i', $m[1])){$a = '-';}return $a;}, $string);

print $string;

这意味着:

  • /([^A-Z0-9]+|\s+|-+)/i这会查找三个量词中的任何一个(任何不是数字或字母,多个空格,多个连字符),如果它匹配其中任何一个,它会将其传递给评估功能。
  • function($m){ ... }这是评估匹配的函数。 $m将保留找到的匹配项。
  • $a = '';为替换
  • 设置空字符串的默认值
  • if(preg_match('/(\s+|-+)/i', $m[1])){$a = '-';}如果我们的匹配(存储在$m[1]中的值)包含多个空格或连字符,请将$a设置为短划线而不是空字符串。
  • return $a;由于这是一个函数,我们将返回该值,并且该值将被放入字符串中找到匹配的位置。

Here is a working demo

答案 2 :(得分:0)

由于您希望用不同的东西替换每个东西,因此您必须在多次迭代中执行此操作。

抱歉D: