我正在尝试从字符串中删除所有前导、尾随和独立连字符
-on-line - auction- website
期望结果:
on-line auction website
我想出了一个可行的解决方案:
^-|(?<='s)-|-(?='s)|-$
但在我看来,它有点业余(不是吗?)那么你有更好的解决方案吗?
您可以使用以下模式:
(?<!'S)-|-(?!'S)
示例:
echo preg_replace('~(?<!'S)-|-(?!'S)~', '', '-on-line - auction- website');
另一种可能使用条件语句的模式:-(?(?!'S)|(?<!'S.))
最后一个很有趣,因为它得益于一个带有前导文字字符的单个分支。通过这种方式,正则表达式引擎能够快速测试字符串中字符出现的位置(由于在"正常"正则表达式引擎遍历之前进行了内部优化)。
注意,条件语句不是强制性的,也可以用添加:
的非捕获组来代替(它不会改变结果,但会更长):
-(?:(?!'S)|(?<!'S.))
我想它可以缩短为:
$repl = preg_replace('/(^|'s)-|-('s|$)/', '$1$2', $str);
您可以尝试以下操作:
-(?!'w)|(?<!'w)-
这要么匹配后面跟着非单词字符的短划线,要么匹配前面跟着非单词字母的短划线。
或者,如果你想换一种方式,匹配所有不在两个单词字符之间的破折号。
Regex101演示
没有理由必须在一个正则表达式中完成所有操作把它分成两个或三个。
s/^-'s*//; # Strip leading hyphens and optional space
s/'s*-$//; # Strip trailing hyphens and optional space
s/'s+-'s+/ /; # Change any space-hyphen-space sequences to a single space.
这就是sed/Perl语法。您将根据preg_replace语法进行相应调整。
在PHP中,您可以使用trim
和rtrim
来删除字符串开头和结尾的任何字符。之后,您可以使用str_replace
从中间移除-
。
$string = '-on-line - auction- website';
$string = trim($string, "-");
$string = rtrim($string,"-");
$string = str_replace("- ", " ", $string);
$string = str_replace(" ", " ", $string); //remove double spaces left by " - "
var_dump($string);
结果:
string(24) "on-line auction website"
如果你想的话,你可以把它叠成一行:
$string = $string = str_replace(" ", " ", str_replace("- ", " ", rtrim(trim($string, "-"),"-")));