在正则表达式中匹配空格

331

如何在 PHP 正则表达式中匹配空格字符?

我的意思是,像 "gavin schulz" 这样,两个单词之间的空格。我正在使用正则表达式来确保只允许字母、数字和一个空格。但我不确定如何找到这个空格。这是我目前的代码:

$newtag = preg_replace("/[^a-zA-Z0-9s|]/", "", $tag);

2
嗯...也没有关于匹配'a'或'b'的问题... ;) - user3850
1
你应该查看正则表达式示例 - T.Todua
10个回答

480
如果您要寻找一个空格,则应使用" "(一个空格)。
如果要查找一个或多个空格,则可以使用" *"(即两个空格和一个星号)或 " +"(一个空格和加号)。
如果您要查找普通间距,请使用"[ X]""[ X][ X]*""[ X]+" 其中X是物理制表符(在所有这些示例中,每个制表符前都有一个空格)。
这些方法适用于我曾见过的所有*正则表达式引擎(其中一些甚至没有单个或多个"+"字符,呃)。
如果您知道将使用更现代的正则表达式引擎,则"\s"及其变体是最佳选择。此外,我认为词边界还可以匹配行的开头和结尾,在查找可能没有前导或后续空格的单词时很重要。
特别针对PHP,此页面可能会有所帮助。
从您的编辑中可以看出,您想要删除所有非有效字符。此始于以下内容(请注意正则表达式中的空格):
$newtag = preg_replace ("/[^a-zA-Z0-9 ]/", "", $tag);
#                                    ^ space here

如果你还想要一些技巧来确保每个单词之间只有一个空格,开头或结尾没有空格,那就需要更复杂一些(也可能是另一个问题),但基本思路如下:

$newtag = preg_replace ("/ +/", " ", $tag); # convert all multispaces to space
$newtag = preg_replace ("/^ /", "", $tag);  # remove space from start
$newtag = preg_replace ("/ $/", "", $tag);  # and end

他原来的正则表达式似乎想要替换空格字符。你正在否定空格,因此他的空格不会按预期被“删除”。 - Suroot
1
引用:“只允许字母、数字和空格”,Gavin原来的正则表达式是错误的(这就是他提出问题的原因)。我的正则表达式会删除所有不属于这些字符的内容。 - paxdiablo
为什么空格必须在匹配模式的末尾而不是中间呢? - warren
1
@warren,这并不影响。'space here'的注释并不是在说明空格去了哪里,而是在说明那里有一个空格(以防读者没有意识到)。 - paxdiablo
@Mike,不是这样的。 这里的意图是替换所有不在集合A-Za-z...中的字符。 方括号内部的插入符号(^)就是这个意思。 将插入符号移到方括号外面会改变其含义,即匹配字符串开头处集合中的字符。 - paxdiablo

88

速查表

下面是有关正则表达式中空格的所有内容的小型速查表:

[[:blank:]]

只匹配空格或制表符,不包括换行符。与写作[ \t]相同。

[[:space:]] & \s

[[:space:]]\s是相同的。它们都将匹配任何空白字符,包括空格、换行符、制表符等。

\v

匹配垂直Unicode空格。

\h

匹配水平空格,包括Unicode字符。它还将匹配空格、制表符、不间断/数学/表意空格。

x(扩展标志)

忽略所有空格。请记住,这是一个标志,因此您将其添加到正则表达式的末尾,例如/hello/gmx。此标志将忽略正则表达式中的空格。

例如,如果您编写像/hello world/x这样的表达式,它将匹配helloworld,但不匹配hello world。扩展标志还允许在正则表达式中使用注释。

示例

/helloworld #hello this is a comment/

如果需要使用空格,可以使用\ 来匹配空格。


并非“万能”的:您还需要知道\s是一个字符类,因此根据语言/方言的不同可能需要用[]()进行包装。 - MarkHu
\s和[]之间有什么区别(即方括号中的空格或字符集内的空格)。它们是否可以互换使用?我可以使用其中任何一个来检测两个单词之间的空格吗? - Priya

59

9
在Perl中,switch是\s(空格)。

32
这是不正确的 - 它收集了所有的空白符,而不仅仅是空格字符。 - J. Taylor
但是问题标记为PHP,而不是Perl。 - Peter Mortensen
3
@PeterMortensen Perl和PHP使用相同的正则表达式引擎PCRE,因此这在PHP中也可以工作。 - Fletcher Rippon

5
我正在使用正则表达式来确保只允许字母、数字和空格。然后只需在现有内容中添加一个空格即可:
$newtag = preg_replace("/[^a-zA-Z0-9 ]/", "", $tag);

(注意,我删除了看起来不是故意的s | ?肯定s是多余的;如果需要,可以恢复|)
如果您特别想要一个空格,例如仅仅是一个,那么您将需要比这更复杂的表达式,并且可能需要考虑单独的非正则表达式逻辑。

4

在这种情况下,使用正则表达式似乎有些杀鸡焉用牛刀。为什么不直接使用strpos来查找空格字符呢?另外,在正则表达式中,空格字符并没有什么特殊之处,你应该能够像查找其他任何字符一样查找它。也就是说,除非你禁用了模式空白,否则在这种情况下几乎没有必要这样做。


3

使用以下方式,以允许一个空格。

$newtag = preg_replace("/[^a-zA-Z0-9\s]/", "", $tag)

2
您可以使用\b来表示单词边界。对于名称,我建议使用以下代码:
[^\b]+\b[^\b]+(\b|$)

编辑 将其修改为Perl示例中的正则表达式

if( $fullname =~ /([^\b]+)\b[^\b]+([^\b]+)(\b|$)/ ) {
 $first_name = $1;
 $last_name = $2;
}

再次编辑 根据您的要求:

$new_tag = preg_replace("/[\s\t]/","",$tag);

单词边界匹配器\b也会匹配连字符。 - Toby 1 Kenobi
在字符类中,一个转义的b代表退格字符,而不是单词边界。 - Casimir et Hippolyte
在字符类中,一个转义的b代表的是一个退格字符,而不是一个词边界。 - undefined

1
我正在尝试在一个实例中使用[[:space:]],这个实例中WordPress博客作者使用了非标准的空格字符。看起来这个方法可行。

“WordPress 中的“博主”是什么意思?能详细说明一下吗?” - Peter Mortensen
@PeterMortensen 这是我为一家主要出版商开发和支持一堆WordPress博客时的情况。作者们在写帖子时使用了一些意外的空格字符。 - Jeremy Schultz

-1

这可以更好地匹配轮胎,因为并非所有供应商都使用相同的尺寸格式。我与许多供应商打交道,他们都使用不同的尺寸格式。目前这是我的表述。

/^[\d][\d](?:\d)?(?:\-|\/|\s)?([?:\d]+)?(?:\.)?(?:\d)?(?:\d)?(?:R|-|\s)?[1-3]([?:[\d]+)?(?:\.)?([?:\d])?(?:\s|-)/img

将捕获所有 35-12.50-22 HAIDA [AA] 35-12-22 HAIDA [AA] 35/35R20 35/35r20 这是一个测试 rrrrr awdg 3345588 225-45-17 ACCELERA [AC]
195 50 16 KELLY 1955016 KELLY CP671" 158 Buckshot 165-40-16-ACHILLES 11-24.5-16-LEAO-LLA08 11-24.5-LEAO-D37 11-22.5-14-LINGLONG-LLD37 11-22.5-HAPPYROAD [AA]


1
请阅读[答案]并[编辑]您的答案,以包含有关此代码实际解决问题的说明。请记住,您不仅要解决问题,还要教育OP和任何未来读者。 - Adriaan

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