如何去除非字母数字字符?

422
我需要从字符串中删除所有不在 a-z A-Z 0-9 集合内或不是空格的字符。
有人有这样做的函数吗?
7个回答

823

听起来你已经知道你想做什么了,你基本上将它定义为一个正则表达式。

preg_replace("/[^A-Za-z0-9 ]/", '', $string);

11
正则表达式工具RegexBuddy对此非常有帮助。 - relipse
3
如果您希望包括连字符作为允许的字符,这是一个例子。我需要使用此功能从 Moodle 用户名中删除基于电子邮件地址的不允许字符:preg_replace("/[^a-z0-9_.@-]/", '', $string); - Evan Donovan
3
这个正则表达式如果使用单引号(撇号)而不是双引号,会完全一样吗?例如:preg_replace('/[^A-Za-z0-9 ]/', '', $string); - 2540625
5
我们需要关于这个的解释 :)。人们来这里是为了了解为什么事情会是这个样子。请考虑提供正则表达式的解释!谢谢。 - Pratik Joshi
4
如果我们想保留重音字符怎么办? - wonzbak
显示剩余3条评论

192

对于Unicode字符,它是:

preg_replace("/[^[:alnum:][:space:]]/u", '', $string);

嗨,Voondo,关于那个 /ui 的东西怎么回事?你叫它什么?能否有人详细解释一下吗?谢谢。 - Kevin Florenz Daus
6
为了澄清,它们被称为标志。它们放置在结束分隔符之后(在这种情况下是“/”,但它也可以是“〜”或“@”或任何你想使用的字符,只要开放和闭合分隔符相同),并改变表达式的行为。 - Doktor J
1
顺便提一下,\w 包括 \d,所以 \d 是不必要的。此外,这是错误的,因为它还会在结果字符串中保留下划线(也包含在 \w 中)。 - smathy
3
还有一个错误,字符类需要以“:]”结尾,所以正确的代码应该是:preg_replace("/[^[:alnum:][:space:]]/ui", '', $string); - h00ligan
5
[:alnum:] 已经包含了大小写字母和数字,这里是否真的需要使用 i 标志呢? - But those new buttons though..
显示剩余2条评论

59

正则表达式就是你的答案。

$str = preg_replace('/[^a-z\d ]/i', '', $str);
  • i 表示不区分大小写。
  • ^ 表示不以...开头。
  • \d 匹配任何数字。
  • a-z 匹配介于 az 之间的所有字符。由于参数中包含 i,因此您不必指定 a-zA-Z
  • \d 后面有一个空格,因此在这个正则表达式中允许出现空格。

4
我们希望你能解释一下这个问题 :)。人们来这里是为了了解它为什么会这样。请考虑对正则表达式进行解释!并不是每个人都足够先进,可以在没有解释的情况下理解你写的内容。谢谢。 - Pratik Joshi
@PratikCJoshi 中的 i 代表不区分大小写。^ 表示不以某个字符开头。\d 匹配任何数字。a-z 匹配 a 到 z 之间的所有字符。由于 i 参数,您不必指定 a-z 和 A-Z。在 \d 后面有一个空格,因此在此正则表达式中允许空格。 - bart
1
人们不会把注释当作答案来阅读,请更新答案! - Pratik Joshi

40

如果需要支持其他语言,可以使用以下方式代替典型的A-Z:

preg_replace('/[^\p{L}\p{N} ]+/', '', $string);
  • [^\p{L}\p{N} ] 定义了一个 否定 字符类(它将匹配未定义的字符):
    • \p{L}: 任意语言中的字母。
    • \p{N}: 任意脚本中的数字字符。
    • : 空格字符。
  • + 贪婪地 匹配该字符类1到无限次

这将保留来自其他语言和脚本的字母和数字以及 A-Z:

preg_replace('/[^\p{L}\p{N} ]+/', '', 'hello-world'); // helloworld
preg_replace('/[^\p{L}\p{N} ]+/', '', 'abc@~#123-+=öäå'); // abc123öäå
preg_replace('/[^\p{L}\p{N} ]+/', '', '你好世界!@£$%^&*()'); // 你好世界

注意: 这是一个非常古老但仍然相关的问题。我回答纯粹是为了提供可能对未来访客有用的补充信息。



3
如果我在正则表达式末尾添加unicode u标志,它对我有效-- /[^\p{L}\p{N} ]+/u - vatavale

17

这是一个非常简单的正则表达式:

\W|_

并且可以根据您的需要使用它(使用前向/斜杠分隔符)。

preg_replace("/\W|_/", '', $string);

使用这个强大的工具来测试正则表达式并了解其工作原理:

http://www.regexr.com/


1
您仍需要/u标志,否则非ASCII字母也将被删除。 - Xeoncross
整洁的但也匹配空格,如果需要,可能可以通过使用字符类和额外的量词来将性能提高一倍,以匹配一个或多个 [\W_]+ - bobble bubble

16
[\W_]+

$string = preg_replace("/[\W_]+/u", '', $string);
它选择所有不是 A-Z、a-z、0-9 的字符并将其删除。
在此处查看示例:https://regexr.com/3h1rj
<?php

$strings="

_____________________
--> Welcome to RegExr v2.1 by gskinner.com, proudly hosted by Media Temple!

Edit the Expression & Text to see matches. Roll over matches or the expression for details. Undo mistakes with ctrl-z. Save Favorites & Share expressions with friends or the Community. Explore your results with Tools. A full Reference & Help is available in the Library, or watch the video Tutorial.

Sample text for testing: ª²³µ - Académie Française ______________---__
abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789 _+-.,!@#$%^&*();\\/|<>\"\'
12345 -98.7 3.141 .6180 9,000 +42
555.123.4567    +1-(800)-555-2468
foo@demo.net    bar.ba@test.co.uk
www.demo.com    http://foo.co.uk/
http://regexr.com/foo.html?q=bar
https://mediatemple.net
";

/* No line break */
$string = preg_replace("/[\W]+/u", '', $strings);
echo "Option 1:".$string;
/* Keep line break */
$string = preg_replace("/[^\n\w]+/u", '', $strings);
echo "\n\nOption 2:". $string;
?>

PHP 8.1.12 的输出

Option 1: _____________________WelcometoRegExrv21bygskinnercomproudlyhostedbyMediaTempleEdittheExpressionTexttoseematchesRollovermatchesortheexpressionfordetailsUndomistakeswithctrlzSaveFavoritesShareexpressionswithfriendsortheCommunityExploreyourresultswithToolsAfullReferenceHelpisavailableintheLibraryorwatchthevideoTutorialSampletextfortestingª²³µAcadémieFrançaise________________abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_1234598731416180900042555123456718005552468foodemonetbarbatestcoukwwwdemocomhttpfoocoukhttpregexrcomfoohtmlqbarhttpsmediatemplenet

Option 2: 

_____________________
WelcometoRegExrv21bygskinnercomproudlyhostedbyMediaTemple

EdittheExpressionTexttoseematchesRollovermatchesortheexpressionfordetailsUndomistakeswithctrlzSaveFavoritesShareexpressionswithfriendsortheCommunityExploreyourresultswithToolsAfullReferenceHelpisavailableintheLibraryorwatchthevideoTutorial

Sampletextfortestingª²³µAcadémieFrançaise________________
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789_
1234598731416180900042
555123456718005552468
foodemonetbarbatestcouk
wwwdemocomhttpfoocouk
httpregexrcomfoohtmlqbar
httpsmediatemplenet

1
这个正则表达式 /[\W_]+/u 是什么意思? - Ângelo Rigo
2
\W\w 的反义词,\w 包括字符 A-Za-z0-9_。因此,\W 将匹配任何不是 A-Za-z0-9_ 的字符并将其删除。[]字符集边界+ 在字符集边界上是多余的,但通常表示一个或多个字符。u 标志扩展了表达式以包括 Unicode 字符支持,这意味着它不会删除超出字符代码 255 的字符,例如 ª²³µ。各种用法的示例 https://3v4l.org/hSVV5 包括 Unicode 和 ASCII 字符。 - Will B.

3

1
根据@Alex Stevens的答案,这无法捕捉下划线“_”。 - Ariel Allon
说实话,下划线不是字母数字字符。 - John

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