不匹配引号中的内容的正则表达式

3

我有一段用于在php preg_match中去除“:”和“(”尾随空格的正则表达式。

([\(:])\s+

我遇到的问题是它会剥夺我在引号内需要的空格。例如,这个字符串:
img[style*="float: left"]

有没有一种方法可以编写正则表达式,使其匹配任何“:”或“(”,除非它被双引号括起来?


如果你只是想寻找行尾空格,那么你可以在正则表达式中添加一个行结束符($),这样就不会匹配字符串内的冒号和括号了。 - mart1n
我想从字符串中去除空格,不仅仅是在行末的空格。我只想跳过用引号括起来的内容。 - Cloudkiller
3个回答

1
你可以尝试这个:

$text = preg_replace('~(?|(\\\{2}|\\\"|"(?>[^"\\\]+|\\\{2}|\\\")*+")|([:(])\s+)~', '$1', $text);

这段内容的翻译如下:

这个想法是匹配([:(])\s+之前的双引号部分,并将其替换为它们自身。

为了避免匹配转义引号,先匹配反斜杠。

模式细节:

~                                    # pattern delimiter
(?|                                  # branch reset : all capture groups inside have the same number
    (                                # open a capturing group
        \\\{2}                       # group of 2 backslashes (can't escape everything)
      |                              # OR
        \\\"                         # an escaped double quote
      |                              # OR
        "(?>[^"\\\]+|\\\{2}|\\\")*+" # content inside double quotes
    )                                # close the capturing group
  |                                  # OR
    ( [:(] )                         # a : or a ( in a capturing group
    \s+                              # spaces
)                                    # close the branch reset group
~                                    # pattern delimiter

我们的目标是处理这种情况:

img: " : \" ( "
img: \" : ( " ( "
img: \\" : ( " ( "

result:

img:" : \" ( "
img:\" :(" ( "
img:\\" : ( " ("

1

描述

此例程将:

  • 跳过引号内找到的匹配项
  • 替换引号外找到的匹配项

演示实例

代码

<?php

$string = 'img[style*="float: left"]
img: [style*="float: left"]
img( [style*="float: left"]
';


    $regex = '/"[^"]*"|([:(])\s+/ims';

    $output = preg_replace_callback(
        $regex,
        function ($matches) {
            if (array_key_exists (1, $matches)) {
                return $matches[1] ;
            }
            return $matches[0];
        },
        $string
    );
    echo "this is the output:"  . $output;

输出

this is the output:img[style*="float: left"]
img:[style*="float: left"]
img([style*="float: left"]

1

有两种方法可以解决这个问题:

  1. 您可以使用负向先行断言(信息在此处),尝试断定您不想被剥离的内容前后没有双引号。我对此的问题是,无法指示引号或者 :( 有多远的距离,而且先行断言无法是未知长度的。

  2. 我喜欢做的事情是,“保留”在双引号中间的任何内容,使用正则表达式 \"[^"]+\" 将其存储在数组中,并用字符串替换它们(我使用“THIS_IS_A_QUOTE”)。将所有引号都存储在数组中后,去除所有空格,最后将所有“THIS_IS_A_QUOTE”字符串恢复为数组中的字符串。


那是一个聪明的做法。如果我不能让其他解决方案起作用,我会尝试第二个。谢谢! - Cloudkiller

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