正则表达式删除除括号之外的所有空格

时间:2009-07-30 21:13:21

标签: php regex

我一直在努力解决我希望用正则表达式解决的问题。

假设我有一个字符串,可以包含任何字母数字,并且子字符串可能被方括号包围。这些子字符串可以像这样出现在字符串中的任何位置。也可以有任意数量的括号子串。

示例:

  • aaa [bb b]
  • aaa [bbb] ccc [d dd]
  • [aaa] bbb [c cc]

你可以看到一些括号中的子串中有空格,这很好。我现在的主要问题是当我在括号外面遇到空格时:

  • a aa [bb b]

现在我想保留括号内的空格,但在其他地方删除它们。

对于像

这样的字符串来说,这会变得有点棘手
  • a aa [bb b] c cc [d dd] e ee [f ff]

在这里,我希望返回:

  • aaa [bb b] ccc [d dd] eee [f ff]

我现在花了一些时间阅读关于外观,消极断言等的不同注册页面,这让我头晕目眩。

注意:对于访问此内容的任何人,我都没有寻找任何涉及嵌套括号的解决方案。如果是这种情况,我可能会像下面提到的一些评论一样务实地做。

6 个答案:

答案 0 :(得分:11)

这个正则表达式可以解决这个问题:

[ ](?=[^\]]*?(?:\[|$))

只需替换与“”匹配的空格。

基本上它所做的就是确保你要移除的空间前面有一个“[”,但如果它前面有一个“]”则没有。

只要你没有嵌套的方括号,那就应该有用,例如:

a a [b [c c] b]

因为在这种情况下,第一个“b”之后的空格将被删除,它将变为:

aa [b [c c] b]

答案 1 :(得分:8)

这听起来不像你真正想要的正则表达式。通过阅读直接解析非常容易。伪代码:

inside_brackets = false;
for ( i = 0; i < length(str); i++) {
    if (str[i] == '[' )
        inside_brackets = true;
    else if str[i] == ']'
        inside_brackets = false;
    if ( ! inside_brackets && is_space(str[i]) )
        delete(str[i]);
}

任何涉及正则表达式的东西都会涉及很多外观,这些东西会反复重复,而且速度会慢得多,而且难以理解。

要使这个适用于嵌套括号,只需将inside_brackets更改为计数器,从零开始,在开括号上递增,在小括号上递减。

答案 2 :(得分:2)

这对我有用:

(\[.+?\])|\s

然后,当您调用replace函数时,只需传入$ 1的替换值。我们的想法是首先在括号内查找图案,并确保它们不受影响。然后括号外的每个空格都被替换为空。

请注意,我使用Regex Hero(.NET正则表达式测试程序)进行了测试,而不是使用PHP进行测试。所以我不能100%确定这对你有用。

这是一个有趣的。一开始听起来很简单,然后看起来相当困难。然后我终于到达的解决方案确实很简单。我很惊讶解决方案不需要任何形式的外观。它应该比使用环视的任何方法都快。

答案 3 :(得分:1)

如何做到这一点取决于应该做什么:

a b [ c [ d [ e ] f ] g

这是模棱两可的;可能的答案至少是:

  • ab[ c [ d [ e ] f ]g
  • ab[ c [ d [ e ]f]g
  • 错误输出;括号不匹配!

对于前两种情况,您可以使用regexp。对于第三种情况,使用(小)解析器会更好。

对于一个或两个案例,在第一个[上拆分字符串。在[之前删除所有内容(显然在括号之外)。接下来,查找.*\](案例1)或.*?\](案例2)并将其移至输出。重复,直到你没有输入。

答案 4 :(得分:1)

重新提出这个问题,因为它有一个简单的解决方案,没有提到。

\[[^]]*\](*SKIP)(*F)|\s+

交替的左侧匹配完整的括号组,然后故意失败。右侧匹配并捕获第1组的空格,我们知道它们是正确的空格,因为如果它们在括号内,则左边的表达式会失败。

查看此demo

中的匹配项

这意味着你可以做到

$replace = preg_replace("~\[[^]]*\](*SKIP)(*F)|\s+~","",$string);

参考

  1. How to match pattern except in situations s1, s2, s3
  2. How to match a pattern unless...

答案 5 :(得分:0)

以下内容将匹配行首或行括结束(必须在您想要匹配的任何空格之前),后跟任何不是括号或空格的内容,后跟一些空格

/((^|\])[^ \[]*) +/

$1替换“all”将从每个非括号序列中删除第一个空格块。您必须重复匹配才能删除所有空格。

示例:

abcd efg [hij klm]nop qrst u
abcdefg [hij klm]nopqrst u
abcdefg[hij klm]nopqrstu
done