【问题标题】:Replace newlines within string except for ones within json替换字符串中的换行符,json 中的换行符除外
【发布时间】:2020-11-24 18:47:31
【问题描述】:

我使用这篇文章作为这个问题的参考 - How do I regex remove whitespace and newlines from a text, except for when they are in a json's string?

我在 java 程序中有以下字符串:

"stuff\n blah\n--payload {'meh': 'kar\n'}"

我正在寻找一个正则表达式来替换整个字符串中的换行符,但 JSON 字符串中的换行符除外。我期待的结果是:

"stuff blah --payload {'meh': 'kar\n'}"

该帖子中引用的正则表达式在大多数情况下都可以正常工作,但也会替换 JSON 字符串中的 \n。我得到的最终结果是:

"stuff blah --payload {'meh': 'kar'}"

我一直在尝试以下一组正则表达式:

^("[^"]*(?:""[^"]*)*")(\n+)  // I expected this to be a combination of newline and newline not within double quotes

[\n\r]\s*  //Match new lines, and then could possibly negate it to be within double quotes?

但我似乎仍然无法获得不会忽略 JSON 值字符串中的换行符的用例。有没有可能的解决方案?

【问题讨论】:

  • "Parsing" JSON with regex... 不会那么好用。除非您确定 JSON 将在 --payload 之后,否则您会遇到一些麻烦,在这种情况下,分两块执行此操作:处理 JSON 有效负载之前的位,然后处理之后的位(可能会忽略它),然后将两个块重新组合在一起。
  • 换句话说,你让问题变得更难了。
  • 使用解析器,而不是正则表达式。这是唯一的方法。
  • 为什么不先排除 JSON(例如,删除以 { 开头并以 } 结尾的字符串),然后删除剩余字符串中的换行符。正如@DaveNewton 所写,将其作为一个字符串处理会使事情变得过于复杂。
  • 好点。我可以使用匹配器来删除 JSON 字符串部分,然后从剩余的字符串中完全去除换行符。

标签: java json regex


【解决方案1】:

我相信你在两个方面过于复杂了:

  1. 对任何涉及 JSON 的事情都使用正则表达式。
  2. 尝试一次求解整个字符串。

JSON

Regex + JSON,比如Regex + HTML TO͇̹̺ͅƝ̴ȳ̳ TH̘Ë͖́̉ ͠P̯͍̭O̚​N̐Y̡ H̸̡̪̯ͨ͊̽̅̾̎Ȩ̬̩̾͛ͪ̈́̀́͘ ̶̧̨̱̹̭̯ͧ̾ͬC̷̙̲̝͖ͭ̏ͥͮ͟Oͮ͏̮̪̝͍M̲̖͊̒ͪͩͬ̚̚͜Ȇ̴̟̟͙̞ͩ͌͝S̨̥̫͎̭ͯ̿̔̀ͅ,只是不要混用。

解决问题

如果 JSON 始终位于末尾,并且始终由已知字符串分隔,您可以:

  • 在最后一个分隔符处拆分字符串(在您的示例中为--payload)。
  • 处理第一个字符串(去掉换行符)。
  • 将它们重新组合在一起。
  • 利润。

【讨论】:

    【解决方案2】:

    这可能会有所帮助:

    public static void main(String[] args) {
        String input = "stuff\n blah\n--payload {'meh': 'kar\n'}";
        // Wanted output: Output: "stuff blah --payload {'meh': 'kar\n'}"
    
        String regexPayload = "--payload\\s[^\\}]+\\}";
        Matcher matcherExtractPayload = Pattern.compile(regexPayload, Pattern.DOTALL).matcher(input);
        Matcher matcherReplaceWithTag = Pattern.compile(regexPayload).matcher(input);
    
        String tag = "#PAYLOAD#";
        String taggedPayload = "EMPTY";
        String payLoad = "NO_PAYLOAD_FOUND";
        if(matcherExtractPayload.find()) {
            payLoad = matcherExtractPayload.group();
            taggedPayload = matcherReplaceWithTag.replaceFirst(tag);
        }
    
        String removedNewline = Pattern.compile("\n").matcher(taggedPayload).replaceAll("");
        String restoredPayload = removedNewline.replaceFirst(tag, " " + payLoad);
    
        System.out.println(restoredPayload); // Output: "stuff blah --payload {'meh': 'kar\n'}"
    }
    

    【讨论】:

      猜你喜欢
      • 2011-08-27
      • 2021-09-26
      • 2010-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-17
      相关资源
      最近更新 更多