wlee1991

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

  •  
  •   wlee1991 · Oct 12, 2016 · 2740 views
    This topic created in 3526 days ago, the information mentioned may be changed or developed.
    <img src="699.jpg" alt="" width="620" height="350" title="" align="" />   太难了。多行汉字。多行汉字。多行汉字。
    	  太难了。  <img src="699.jpg" alt="" width="620" height="350" title="" align="" />
    多行汉字。多行汉字。多行汉字。多行汉字。
      怎么办。呵呵
    
    13 replies    2016-10-15 08:35:44 +08:00
    soratadori
        1
    soratadori  
       Oct 12, 2016
    零宽断言
    aploium
        2
    aploium  
       Oct 12, 2016
    ```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  
       Oct 12, 2016
    为什么不支持 markdown - -
    sutra
        4
    sutra  
       Oct 12, 2016
    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  
       Oct 12, 2016
    上面这个漏了一种 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  
       Oct 12, 2016
    @sutra 还有一种恶心的 case:
    ```
    <tag/> 我在 tag 外面 > > ←这是两个不规范的→尖括号
    ```
    msg7086
        7
    msg7086  
       Oct 13, 2016
    只有我会去 capture >和<之间的内容然后把 capture 到的文字拿去抹空格么……
    msg7086
        8
    msg7086  
       Oct 13, 2016
    s.gsub(/>[^<]+</) {|ss| ss.delete(' ')}
    wlee1991
        9
    wlee1991  
    OP
       Oct 13, 2016
    @msg7086 最终还是要获得去掉空格之后的所有内容,包括尖括号里面的;
    nicoljiang
        10
    nicoljiang  
    PRO
       Oct 13, 2016
    比较严禁的处理思路大概是类似这样的吧:

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

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

    这样执行效率可能略低,但比较准确。
    wlee1991
        11
    wlee1991  
    OP
       Oct 13, 2016
    @nicoljiang 谢谢,后来确实也是这么做了。
    msg7086
        12
    msg7086  
       Oct 15, 2016
    @wlee1991 是啊,返回的不就是所有内容么。
    Capture 是做替换啊。替换完了以后还是所有的内容。
    msg7086
        13
    msg7086  
       Oct 15, 2016
    @nicoljiang 很多正则函数都支持一边替换一边处理的。比如 PHP 里:
    http://php.net/manual/zh/function.preg-replace-callback.php
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5480 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 71ms · UTC 08:52 · PVG 16:52 · LAX 01:52 · JFK 04:52
    ♥ Do have faith in what you're doing.