PHP去除标点符号

33

假设现在我有这个:

$hello = "Hello, is StackOverflow a helpful website!? Yes!";

我想去除标点符号,使其输出为:

hello_is_stackoverflow_a_helpful_website_yes

我该如何做到这一点?

4个回答

58
# to keep letters & numbers
$s = preg_replace('/[^a-z0-9]+/i', '_', $s); # or...
$s = preg_replace('/[^a-z\d]+/i', '_', $s);

# to keep letters only
$s = preg_replace('/[^a-z]+/i', '_', $s); 

# to keep letters, numbers & underscore
$s = preg_replace('/[^\w]+/', '_', $s);

# same as third example; suggested by @tchrist; ^\w = \W
$s = preg_replace('/\W+/', '_', $s);

对于字符串

$s = "Hello, is StackOverflow a helpful website!? Yes!";

结果(适用于所有示例)为

Hello_is_StackOverflow_a_helpful_website_Yes_

享受吧!


嗯...但是如果我有Hello, world!,当应该只有一个下划线代表空格时,我会得到hello__world - test
1
\W 的方式真奇怪! - tchrist

18
function strip_punctuation($string) {
    $string = strtolower($string);
    $string = preg_replace("/[:punct:]+/", "", $string);
    $string = str_replace(" +", "_", $string);
    return $string;
}

首先将字符串转换为小写,然后删除标点符号,接着将空格替换为下划线(这将处理一个或多个空格,所以如果有人输入两个空格,它将被替换为一个下划线)。


1
“\pP” 不是指定标点符号的现代方式吗? - tchrist
@tchrist 在 POSIX、GNU 和 PCRE 正则表达式中,最兼容和可读的方法是使用 POSIX 字符类,如 [:alnum:][:punct:]\pP 依赖于 Unicode 的东西,在 PHP 中如何处理我不知道,因为 PHP 支持 Unicode 的方式很糟糕。 - Rafe Kettler
2
如果你想要可读性,那么你应该使用完整的属性名称:\p{General_Category=Punctuation},通常缩写为类似于二进制属性的\p{Punctuation}。不幸的是,PCRE 对 Unicode 属性的支持不够好。我永远不会相信 POSIX 字符类,因为它们太容易受到供应商区域设置和用户设置的影响而出现故障。即使这是 UTS#18 的 RL1.2 所要求的,它几乎从不正确地处理 Unicode。我不信任和不喜欢任何不支持 Unicode 的东西。 - tchrist
至于兼容性,您绝对需要Unicode属性而不是不可靠的旧POSIX字符类。这是因为Unicode属性比POSIX字符类更加便携,因为Unicode的\pP“标点符号属性”始终适用于所有Unicode标点符号,无论当前使用了什么样的区域设置或供应商是否已经实现它们或者他们是否跟上了Unicode标准,他们都非常缓慢。 - tchrist
3
由于某些原因,/[:punct:]+/ 抛出了语法错误,但 /[[:punct:]]+/ 没有。 - Rohn Adams

11

没有正则表达式的情况下:

<?php
  $hello = "Hello, is StackOverflow a helpful website!? Yes!"; // original string
  $unwantedChars = array(',', '!', '?'); // create array with unwanted chars
  $hello = str_replace($unwantedChars, '', $hello); // remove them
  $hello = strtolower($hello); // convert to lowercase
  $hello = str_replace(' ', '_', $hello); // replace spaces with underline
  echo $hello; // outputs: hello_is_stackoverflow_a_helpful_website_yes
?>

4
我会选择类似这样的东西:

我会选择这样的东西:

$str = preg_replace('/[^\w\s]/', '', $str);

我不确定这是否比你要求的更广泛,但听起来像是你想要做的事情。
我还注意到你在示例中使用下划线替换了空格。我会使用以下代码来实现:
$str = preg_replace('/\s+/', '_', $str);

请注意,这也会将多个空格合并为一个下划线。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接