当前位置: 首页 > 知识库问答 >
问题:

Regex:以消息和父消息之间的字符串开头

盖弘毅
2023-03-14

我想得到所有的消息数据。这样它就应该在父消息的花括号之间查找消息和所有数据。有了下面的模式,我没有得到所有的父体。

 String data = "syntax = \"proto3\";\r\n" + 
            "package grpc;\r\n" + 
            "\r\n" + 
            "import \"envoyproxy/protoc-gen-validate/validate/validate.proto\";\r\n" + 
            "import \"google/api/annotations.proto\";\r\n" + 
            "import \"google/protobuf/wrappers.proto\";\r\n" + 
            "import \"protoc-gen-swagger/options/annotations.proto\";\r\n" + 
            "\r\n" + 
            "message Acc {\r\n" + 
            "    message AccErr {\r\n" + 
            "        enum Enum {\r\n" + 
            "            UNKNOWN = 0;\r\n" + 
            "            CASH = 1;\r\n" + 
            "        }\r\n" + 
            "    }\r\n" + 
            "    string account_id = 1;\r\n" + 
            "    string name = 3;\r\n" + 
            "    string account_type = 4;\r\n" + 
            "}\r\n" + 
            "\r\n" + 
            "message Name {\r\n" + 
            "    string firstname = 1;\r\n" + 
            "    string lastname = 2;\r\n" + 
            "}";
        List<String> allMessages = new ArrayList<>();
        Pattern pattern = Pattern.compile("message[^\\}]*\\}");
        Matcher matcher = pattern.matcher(data);
        while (matcher.find()) {
            String str = matcher.group();
            allMessages.add(str);
            System.out.println(str);
        }
    }
    

在我的字符串数组列表中,我希望得到如下大小为2的响应。

allMessage。get(0)应该是:

message Acc {
    message AccErr {
        enum Enum {
            UNKNOWN = 0;
            CASH = 1;
        }
    }
    string account_id = 1;
    string name = 3;
    string account_type = 4;
}

allMessage。get(1)应该是:

message Name {
    string firstname = 1;
    string lastname = 2;
}

共有2个答案

艾晋
2023-03-14

试试你的正则表达式。它锚定在消息作为一行的开头,并使用正向前瞻查找下一条消息或消息的结尾。

Pattern.compile("(?s)\r\n(message.*?)(?=(\r\n)+message|$)")
// or
Pattern.compile("(?s)\r?\n(message.*?)(?=(\r?\n)+message|$)")

也没有拆分、解析或管理嵌套大括号:)

https://regex101.com/r/Wa2xxx/1

白青青
2023-03-14

首先删除之前的输入消息出现在行的开始,然后拆分在换行符后的消息(包括换行符在拆分中,所以干预父消息的换行符被消耗):

String[] messages = data.replaceAll("(?sm)\\A.*?(?=message)", "").split("\\R+(?=message)");

观看现场演示。

如果你真的需要一个列表

List<String> = Arrays.asList(data.replaceAll("(?sm)\\A.*?(?=message)", "").split("\\R+(?=message)"));

第一个正则表达式匹配从启动到第一行的所有内容,但不包括以消息开头的第一行,该行被替换为空白(即已删除)。打破僵局:

  • (?sm)打开标志s,它使点也匹配换行符;和m,它使^$匹配每行的开始和结束
  • \\A表示输入的开始
  • * * 指任何字符的任何数量(包括根据设置的s标志换行),但添加使其变得不情愿,因此它在仍然匹配的情况下匹配尽可能少的字符
  • (?=^message)是向前看的,表示以下字符是一行的开头,然后是“message”

有关详细说明,请参见regex101实时演示。

split regex与一个或多个换行符序列相匹配,它们后面跟有“message”

  • \\R表示一个或多个换行序列(所有OS变体)
  • (?=消息)是一个展望,意味着以下字符是消息

有关详细说明,请参见regex101实时演示。

 类似资料:
  • 我只想得到所有的消息数据。这样它就应该在父消息的花括号之间查找消息和所有数据。有了下面的代码,我也得到了服务细节以及我不想要的消息。对此专家的任何建议都要提前感谢。 我期待响应如下在我的字符串大小为2的数组列表。 好的。get(0)应该是 好的。get(1)应该是

  • 我想从输入(proto文件)中获取所有消息块。我在下面写了regex方法,但regex模式不匹配。专家们有什么建议吗?提前谢谢。 我的原始文件,我作为字符串发送到上面的方法

  • 问题内容: 我对SOAP消息和WSDL如何组合在一起感到困惑?我已经开始研究SOAP消息,例如: 是否所有SOAP消息都是WSDL?SOAP是接受其自己的“ SOAP消息”或“ WSDL”的协议吗?如果它们不同,那么我什么时候应该使用SOAP消息,什么时候应该使用WSDL? 关于此的一些说明将是很棒的。 问题答案: 每个请求都会发送一个SOAP文档。假设我们是一家书店,并且拥有一台远程服务器,我们

  • 我对SOAP消息和WSDL如何结合感到困惑?我已经开始研究SOAP消息,例如: 所有SOAP消息都是WSDL的吗?SOAP是接受自己的“SOAP消息”还是“WSDL”的协议?如果它们不同,那么什么时候应该使用SOAP消息,什么时候应该使用WSDL消息? 关于这一点的一些澄清将是非常棒的。

  • 我是一个新的Kafka和使用Apache kafka消费者读取消息从生产者。但当我停下来开始一段时间。之间产生的所有消息都将丢失。如何处理这种情况。我正在使用这些属性“auto.offset.reset”、“latest”和“enable.auto.commit”、“false”。 这是我正在使用的代码。任何帮助都是感激的。

  • 我调用方法从一个工人线程在下面的代码,但Android不抛出这应该说java.lang.IllegalStateExc0019:调用视图方法在另一个线程比UI线程”,因为我正在修改UI从外部的UI线程,这在Android中是禁止的。 以下是我的工作线程作为内部类的可运行状态: 注意:host OnHoldDialog是我活动的成员。 而不是抛出,android只是不根据消息更新UI。 这是虫子吗?