找到“消息:”后如何停止正则表达式?

时间:2019-07-17 18:34:26

标签: java json regex

我正在用正则表达式“:| \ n”拆分JSON消息的正文并将值存储到数组中。一旦找到“ Message:”,我想获得帮助以阻止我的正则表达式拆分消息。

在JSON主体中,每个部分都由换行符分隔,因此主体看起来类似于:

{“ body”:“名称:Alfred Alonso \ n公司:null \ n电子邮件:123@abc.com \ n电话号码:123-456-9999 \ n项目类型:现有\ n联系方式:电子邮件\ n时间范围:1内month \ n消息:您好,\ n这是我的消息。\ n谢谢您,\ nJohn Doe“}

当用户未在消息中创建新行时,以下代码可以完美工作,因此整个消息将存储为一个数组值。

感谢任何可以帮助我解决此问题的人!

String[] messArr = body.split(":|\n");

    for (int i = 0; i < messArr.length; i++)
        messArr[i] = messArr[i].trim();

    if ("xxx".equals(eventSourceARN)) {

        name = messArr[1];

        String[] temp;
        String delimiter = " ";

        temp = name.split(delimiter);
        name = temp[0];
        String lastName = temp[1];

        company = messArr[3];
        email = messArr[5];
        phoneNumber = messArr[7];
        projectType = messArr[9];
        contactBy = messArr[11];
        timeFrame = messArr[13];
        message = messArr[15];

我想要

messArr[14] = "Message"
messArr[15] = "Hello, This is my message. Thank you, John Doe"

这就是我得到的 [...,消息,您好,这是我的消息。,谢谢,约翰·多伊]。

messArr[14] = "Message"
messArr[15] = "Hello,"
messArr[16] = "This is my message."
messArr[17] = "Thank You,"
messArr[18] = "John Doe"

2 个答案:

答案 0 :(得分:0)

例如,可以使用split循环来代替find

Pattern p = Pattern.compile("([^:\\v]+): |((?<=Message: )(?s:.*)|(?<!$).*)\\R?");
List<String> result = new ArrayList<>();
for (Matcher m = p.matcher(input); m.find(); )
    result.add(m.start(1) != -1 ? m.group(1) : m.group(2));

测试

String input = "Name: Alfred Alonso\n" +
               "Company: null\n" +
               "Email: 123@abc.com\n" +
               "Phone Number: 123-456-9999\n" +
               "Project Type: Existing\n" +
               "Contact by: Email\n" +
               "Time Frame: within 1 month\n" +
               "Message: Hello,\n" +
               "This is my message.\n" +
               "Thank You,\n" +
               "John Doe";

Pattern p = Pattern.compile("([^:\\v]+): |((?<=Message: )(?s:.*)|(?!$).*)\\R?");
List<String> result = new ArrayList<>();
for (Matcher m = p.matcher(input); m.find(); )
    result.add(m.start(1) != -1 ? m.group(1) : m.group(2));
for (int i = 0; i < result.size(); i++)
    System.out.println("result[" + i + "]: " + result.get(i));

输出

result[0]: Name
result[1]: Alfred Alonso
result[2]: Company
result[3]: null
result[4]: Email
result[5]: 123@abc.com
result[6]: Phone Number
result[7]: 123-456-9999
result[8]: Project Type
result[9]: Existing
result[10]: Contact by
result[11]: Email
result[12]: Time Frame
result[13]: within 1 month
result[14]: Message
result[15]: Hello,
This is my message.
Thank You,
John Doe

说明

  • 符合以下条件之一:
    • (开始捕获#1
      • [^:\v]+匹配一个或多个不是:或换行符的字符
    • )结束捕获#1
    • :匹配但不捕获:和空格(SO隐藏在此处)
  • |或:
    • (开始捕获#2
      • 符合以下条件之一:
        • (?<=Message: )(?s:.*)输入的其余部分,即包括换行符的所有文本,如果该文本紧随其后是“消息:”
      • |或:
        • (?!$)如果我们已经输入完毕,则不匹配
        • .*匹配0个或更多字符直到行尾,但EOL除外
    • )结束捕获#2
    • \\R?匹配但不捕获可选的换行符。这不适用于Message文本,并且在没有Message文本且上一个值之后没有换行符的情况下是可选的

答案 1 :(得分:0)

如果愿意,您可以完全按照自己的方式做,然后再将它们放在一起。进行修剪时,请注意消息的显示位置,然后知道该消息位于下一个插槽中。然后放回去。

int messagePosition = -1;
for (int i = 0; i < messArr.length; i++){
    messArr[i] = messArr[i].trim();
    if (i>0 && messArr[i-1].equals("Message")){
        messagePosition =i;
    }
}
if (messagePosition > -1){
    for (int i=messagePosition+1; i <messArr.length; i++){
        messArr[messagePosition]=messArr[messagePosition]+" "+messArr[i];
    }
}

一个缺点是,由于数组是固定大小的,因此您需要采取行动,好像在messagePosition之外什么也没有。因此,任何带有长度的计算都将产生误导。如果出于某种原因担心您会寻找其他插槽,可以在串联步骤之后将messArr[i]="";添加到第二个for循环中。