我想从用户输入创建一个url友好字符串(一个只包含字母,数字和连字符的字符串):
预期产出:
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
有没有办法用一个正则表达式做到这一点?
答案 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;
由于这是一个函数,我们将返回该值,并且该值将被放入字符串中找到匹配的位置。答案 2 :(得分:0)
由于您希望用不同的东西替换每个东西,因此您必须在多次迭代中执行此操作。
抱歉D: