Java 正则表达式删除除关键字周围和引号之间的所有空白

Java 正则表达式删除除关键字周围和引号之间的所有空白,java,regex,Java,Regex,我想: 删除所有空格,除非它正好位于预定义关键字的前面或后面(前面0-1个空格,后面0-1个空格)(例如:and,or,如果我们在“and”或“and”或“or”和“unchanged”中保留空格) 忽略引号之间的所有内容 我试过很多模式。我找到的最接近的是非常接近的,但它仍然会删除关键字后的空格,这是我试图避免的 正则表达式: \s(?!and|or|if)(?=(?:[^"]*"[^"]*")*[^"]*$) 测试字符串: if (ans(this) >

我想:

  • 删除所有空格,除非它正好位于预定义关键字的前面或后面(前面0-1个空格,后面0-1个空格)(例如:and,or,如果我们在“and”或“and”或“or”和“unchanged”中保留空格)

  • 忽略引号之间的所有内容

  • 我试过很多模式。我找到的最接近的是非常接近的,但它仍然会删除关键字后的空格,这是我试图避免的

    正则表达式:

    \s(?!and|or|if)(?=(?:[^"]*"[^"]*")*[^"]*$)
    
    测试字符串:

                if    (ans(this) >= ans({1,2})  and (cond({3,4})  or ans(this) <= ans({5,6})), 7, 8)  and {111} > {222}  or ans(this) = "hello    my friend and  or  " and(cond({1,2}) $1 123     
    
    if(ans(this)>=ans({1,2})和(cond({3,4})或ans(this){222}或ans(this)=“你好,我的朋友和或”和(cond({1,2})$1123
    
    理想结果:

     if (ans(this)>=ans({1,2}) and (cond({3,4}) or ans(this)<=ans({5,6})),7,8) and {111}>{222} or ans(this)="hello    my friend and  or  " and(cond({1,2})$1123
    
    if(ans(this)>=ans({1,2})和(cond({3,4})或ans(this){222}或ans(this)=“你好,我的朋友和或”和(cond({1,2})$1123
    
    然后我可以在java中使用
    str=str.replaceAll
    删除这些空白。我不介意通过多个步骤来获得结果,但我对正则表达式不太熟悉,所以有点卡住了

    任何帮助都将不胜感激


    注意:我编辑了结果。对此很抱歉。对于关键字周围的空格:如果有空格,则收缩为1。如果为0,则保留它或添加1个空格(我只是不希望“或ans”变为“orans”,但“and(cond”变为“and(cond)”可以(如果存在,则收缩为1个空格之前和1个空格之后)。忽略引号之间的所有内容。

    你巧妙地利用了捕获组。这里的总体思路是

    match_this|or_this|or_even_this|(but_capture_this)
    
    就正则表达式而言,这可能是

    (?:(?:\s+(?:and|or|if)\s+)|"[^"]+")|(\s+)
    
    只有在第一个捕获组不为空时,才需要替换匹配项。

    请参阅(具有相同用途的
    (*跳过*)(*失败)

    您可以使用

    String example = "            if    (ans(this) >= ans({1,2})  and (cond({3,4})  or ans(this) <= ans({5,6})), 7, 8)  and {111} > {222}  or ans(this) = \"hello    my friend and  or  \" and(cond({1,2}) $1 123    ";
    String rx = "\\s*\\b(and|or|if)\\b\\s*|(\"[^\"]*\")|(\\s+)";
    Matcher m = Pattern.compile(rx).matcher(example);
    example = m.replaceAll(r -> r.group(3) != null ? "" : r.group(2) != null ? r.group(2) : " " + r.group(1) + " ").trim();
    System.out.println( example );
    
    String example=“如果(ans(this)>=ans({1,2})和(cond({3,4})或ans(this){222}或ans(this)=\“你好,我的朋友和或\”和(cond({1,2})$1123”;
    字符串rx=“\\s*\\b(和|或|如果)\\b\\s*\(\“[^\”]*\”))|(\\s+);
    Matcher m=Pattern.compile(rx.Matcher)(示例);
    示例=m.replaceAll(r->r.group(3)!=null?”:r.group(2)!=null?r.group(2):“+r.group(1)+”).trim();
    System.out.println(示例);
    

    模式匹配

    • \s*\b(和|或|如果)\b\s*
      -0+空格,单词边界,第1组:
      如果
      ,单词边界,然后是0+空格
    • |
      -或
    • (\“[^\“]*\”
      -第2组:
      ,除
      之外的任何0+字符,然后是一个
    • |
      -或
    • (\s+)
      -第3组:1+空格

    如果第3组匹配,则将其删除;如果第2组匹配,则将其放回结果中;如果第1组匹配,则将其用空格包装并粘贴回结果中。整个结果是
    .trim()
    ed.

    有时正则表达式并不是最好的解决方案;它们变得复杂、脆弱且无法维护-例如,您是否希望它处理转义引号,如
    ans(this)=“this quote\”转义
    ?您有什么理由希望使用正则表达式而不是代码解析吗?您的问题的预期结果不清楚。您可以修复理想的结果部分吗。Yuk…但它似乎做了一些与所需输出类似的事情:
    str=str.replaceAll(\\s+(?=(?:[^\“]*\”[^\“]*\”[^\“]*$),”).replaceAll(“if=(?::[^\\\\\']*\”[^\'*\”[^\]*$),“if”).replaceAll(“and(?=(?:[^\“]*\”[^\“]*\”*[^\“]*$)”、“and”).replaceAll(“or(?=(?:[^\“]*\”[^\“]*\”[^\“]*$”、“or”);
    。因此必须删除
    “…”
    周围的空格,对吗?必须删除前导/尾随空格?内部空格应收缩为单个空格?并且
    ans({.4,6}
    .ans(
    ->1,1)
    实际上不是您所期望的,对吗?您希望数字保持不变,对吗?请尝试。在您上次编辑之前,我有一个稍微不同的解决方案,它可能仍然很好,但这一个更简单。如果它不起作用,请添加更多测试用例。