PHP正则表达式 - 删除所有前导,尾随和独立连字符

时间:2013-11-26 13:55:13

标签: php regex preg-replace

我正在尝试从字符串中删除所有前导,尾随和独立的连字符:

-on-line - auction- website

期望的结果:

on-line auction website

我提出了一个有效的解决方案

^-|(?<=\s)-|-(?=\s)|-$

但它看起来有点业余(不是吗?)。 您有更好的解决方案吗?

5 个答案:

答案 0 :(得分:4)

您可以使用此模式:

(?<!\S)-|-(?!\S)

示例:

echo preg_replace('~(?<!\S)-|-(?!\S)~', '', '-on-line - auction- website');

另一种使用条件语句的可能模式:-(?(?!\S)|(?<!\S.))

这最后一个很有意思,因为它有一个带有前导文字字符的单个分支的好处。这样,正则表达式引擎只能快速测试字符出现的字符串中的位置(由于在“正常”正则表达式引擎行走之前的内部优化)。

请注意,条件语句不是必需的,也可以替换为添加:的非捕获组(它不会更改结果,但会更长):

-(?:(?!\S)|(?<!\S.))

答案 1 :(得分:3)

我想它可以缩短为:

$repl = preg_replace('/(^|\s)-|-(\s|$)/', '$1$2', $str);

答案 2 :(得分:2)

没有理由你必须在一个正则表达式中执行所有操作。将其拆分为两个或三个。

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语法进行相应调整。

答案 3 :(得分:2)

您可以尝试以下操作:

-(?!\w)|(?<!\w)-

这可以匹配短划线,后面跟不是单词字符的东西,或者前面跟不是单词字符的短划线。

或者如果你想把它放在其他位置,请匹配不在两个单词字符之间的所有短划线。

Regex101 Demo

答案 4 :(得分:1)

在PHP中,您可以使用trimrtrim从字符串的开头和结尾删除任何字符。之后,您可以使用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, "-"),"-")));