怎么用正则去匹配尖括号之外的所有空格? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wlee1991
V2EX    正则表达式

怎么用正则去匹配尖括号之外的所有空格?

  •  
  •   wlee1991 2016-10-12 17:11:41 +08:00 2509 次点击
    这是一个创建于 3331 天前的主题,其中的信息可能已经有所发展或是发生改变。
    <img src="699.jpg" alt="" width="620" height="350" title="" align="" /> 太难了。多行汉字。多行汉字。多行汉字。 太难了。 <img src="699.jpg" alt="" width="620" height="350" title="" align="" /> 多行汉字。多行汉字。多行汉字。多行汉字。 怎么办。呵呵 
    13 条回复    2016-10-15 08:35:44 +08:00
    soratadori
        1
    soratadori  
       2016-10-12 18:52:09 +08:00
    零宽断言
    aploium
        2
    aploium  
       2016-10-12 22:59:00 +08:00
    ```python
    # Python 3
    impor re
    # text = 你上面的那段
    result = re.sub(r"""(?<!<)([^>]*?)( )(?![^<]*>)""", "\g<1>+", text)
    print(result)
    ```

    上面这段正则把尖括号之外的空格替换为加号(+)
    能力有限, 不知道怎么把第一个捕获括号变成非捕获的. 因为 python 要求 look-behind 必须是 fixed-width pattern
    结果为:
    ```
    <img src="699.jpg" alt="" width="620" height="350" title="" align="" />+++太难了。多行汉字。多行汉字。多行汉字。
    ++太难了。++<img src="699.jpg" alt="" width="620" height="350" title="" align="" />
    多行汉字。多行汉字。多行汉字。多行汉字。
    ++怎么办。呵呵
    ```
    注意其中有一行的开头是 Tab, 不是空格, 所以没替换掉
    aploium
        3
    aploium  
       2016-10-12 22:59:17 +08:00
    为什么不支持 markdown - -
    sutra
        4
    sutra  
       2016-10-12 23:00:35 +08:00
    public class Regex {

    public static void main(String[] args) {
    String s = " 太难了。多行汉字。\n 多行汉字。多行汉字。 太难了。 <img src=\"699.jpg\" alt=\"\" width=\"620\" height=\"350\" title=\"\" align=\"\" /> 太难了。多行汉字。\n 多行汉字。多行汉字。 太难了。 <img src=\"699.jpg\" alt=\"\" width=\"620\" height=\"350\" title=\"\" align=\"\" /> 多行汉字。\n 多行汉字。多行汉字。多行汉字。";
    s = s.replaceAll("([ ]+)(?![^<]*>|[^<>]*</)", "");
    System.out.println(s);
    }

    }
    sutra
        5
    sutra  
       2016-10-12 23:06:59 +08:00
    上面这个漏了一种 case <tag></tag>

    package com.oxerr.sandbox;

    public class Regex {

    public static void main(String[] args) {
    String s = " 太难了。多行汉字。\n 多行汉字。多行汉字。 太难了。 <br /> <span> aa </span> <img src=\"699.jpg\" alt=\"\" width=\"620\" height=\"350\" title=\"\" align=\"\" /> 太难了。多行汉字。\n 多行汉字。多行汉字。 太难了。 <img src=\"699.jpg\" alt=\"\" width=\"620\" height=\"350\" title=\"\" align=\"\" /> 多行汉字。\n 多行汉字。多行汉字。多行汉字。";
    s = s.replaceAll("([ ]+)(?![^<]*>)", "");
    System.out.println(s);
    }

    }
    aploium
        6
    aploium  
       2016-10-12 23:16:18 +08:00
    @sutra 还有一种恶心的 case:
    ```
    <tag/> 我在 tag 外面 > > ←这是两个不规范的→尖括号
    ```
    msg7086
        7
    msg7086  
       2016-10-13 02:44:26 +08:00
    只有我会去 capture >和<之间的内容然后把 capture 到的文字拿去抹空格么……
    msg7086
        8
    msg7086  
       2016-10-13 02:54:25 +08:00
    s.gsub(/>[^<]+</) {|ss| ss.delete(' ')}
    wlee1991
        9
    wlee1991  
    OP
       2016-10-13 10:32:01 +08:00
    @msg7086 最终还是要获得去掉空格之后的所有内容,包括尖括号里面的;
    nicoljiang
        10
    nicoljiang  
    PRO
       2016-10-13 11:18:48 +08:00
    比较严禁的处理思路大概是类似这样的吧:

    第一种方案:
    1. 最小匹配所有的<.*?>,把每个匹配出来的段落存到 hash 中,并把他们替换成相应 key 作为代号;
    2. 去所有空格;
    3. 把所有在第一步中替换成的 key 代号变回相应的<.*?>中。

    第二种方案:
    1. 最小匹配所有的<.*?>,并把匹配内容的空格替换成某个代号;
    2. 把全文所有空格去掉;
    3. 再把第一步中的代号替换回空格。

    这样执行效率可能略低,但比较准确。
    wlee1991
        11
    wlee1991  
    OP
       2016-10-13 21:46:37 +08:00
    @nicoljiang 谢谢,后来确实也是这么做了。
    msg7086
        12
    msg7086  
       2016-10-15 08:34:12 +08:00
    @wlee1991 是啊,返回的不就是所有内容么。
    Capture 是做替换啊。替换完了以后还是所有的内容。
    msg7086
        13
    msg7086  
       2016-10-15 08:35:44 +08:00
    @nicoljiang 很多正则函数都支持一边替换一边处理的。比如 PHP 里:
    http://php.net/manual/zh/function.preg-replace-callback.php
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     4190 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 00:12 PVG 08:12 LAX 16:12 JFK 19:12
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86