drgaeqdqiiyg14608 2018-05-13 18:38
浏览 50
已采纳

php - > preg_replace - >仅在引号之间删除空格

I'm trying to remove space ONLY between quotes like:

$text = 'good with spaces "here all spaces should be removed" and here also good';

can someone help with a working piece of code ? I already tried:

$regex = '/(\".+?\")|\s/';

or

$regex = '/"(?!.?\s+.?)/';

without success, and I found a sample that works in the wrong direction :-( Removing whitespace-characters, except inside quotation marks in PHP? but I can't change it.

thx Newi

  • 写回答

2条回答 默认 最新

  • dpdt79577 2018-05-13 18:59
    关注

    This kind of problem are easily solved with preg_replace_callback. The idea consists to extract the substring between quotes and then to edit it in the callback function:

    $text = preg_replace_callback('~"[^"]*"~', function ($m) {
        return preg_replace('~\s~', '#', $m[0]);
    }, $text);
    

    It's the most simple way.


    It's more complicated to do it with a single pattern with preg_replace but it's possible:

    $text = preg_replace('~(?:\G(?!\A)|")[^"\s]*\K(?:\s|"(*SKIP)(*F))~', '#', $text);
    

    demo

    Pattern details:

    (?:
        \G (?!\A)  # match the next position after the last successful match
      |
        "          # or the opening double quote
    )
    [^"\s]*        # characters that aren't double quotes or a whitespaces
    \K             # discard all characters matched before from the match result
    (?:
        \s         # a whitespace
      |
        "           # or the closing quote
        (*SKIP)(*F) # force the pattern to fail and to skip the quote position
                    # (this way, the closing quote isn't seen as an opening quote
                    # in the second branch.)
    )
    

    This way uses the \G anchors to ensure that all matched whitespaces are between the quotes.

    Edge cases:

    • there's an orphan opening quote: In this case, all whitespaces from the last quote until the end of the string are replaced. But if you want you can change this behavior adding a lookahead to check if the closing quote exists:

      ~(?:\G(?!\A)|"(?=[^"]*"))[^"\s]*\K(?:\s|"(*SKIP)(*F))~

    • double quotes can contain escaped double quotes that have to be ignored: You have to describe escaped characters like this:

      ~(?:\G(?!\A)|")[^"\s\\\\]*+(?:\\\\\S[^"\s\\\\]*)*+(?:\\\\?\K\s|"(*SKIP)(*F))~


    Other strategy suggested by @revo: check if the number of remaining quotes at a position is odd or even using a lookahead:

    \s(?=[^"]*+(?:"[^"]*"[^"]*)*+")
    

    It is a short pattern, but it can be problematic with long strings since for each position with a whitespace you have to check the string until the last quote with the lookahead.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化
  • ¥15 Mirare PLUS 进行密钥认证?(详解)
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
  • ¥20 想用ollama做一个自己的AI数据库
  • ¥15 关于qualoth编辑及缝合服装领子的问题解决方案探寻
  • ¥15 请问怎么才能复现这样的图呀