使用正则表达式阅读聊天消息

时间:2016-07-08 17:30:43

标签: java regex

我在Java中使用regex来读取文本文件中的消息内容,其中每个会话的格式都是:

02/05 / 16,12:05 AM - +91 00580 00000:您好

02/05/16,12:06 AM - Ross Clark:你好!

我已经形成了以下模式: \d\d/\d\d/\d\d,\s\d{1,2}:\d\d(\s\w\w)?\s-\s((\w+\s?\w+)|(\+\d{2}\s\d{5}\s\d{5})): ((.*)(\n)*(.*))+

问题是输出显示了具有发件人姓名的聊天记录,例如在上面的聊天示例中,由Ross Clark发送的消息'是匹配的但是号码为+91 00580 00000的消息不匹配。但是,当一些带有数字的消息匹配时,也会出现一些罕见的情况。

请帮助,我是新手。

编辑:我想知道发件人的名字或号码是什么时候,即我希望这个名字被一个组别和另一个号码捕获,所以我可以区分。

3 个答案:

答案 0 :(得分:1)

如果您知道邮件的格式及其类似内容:

 <Date>, <Time> - ‪<NameOrNumber>‬: <Message>

然后,您可以在-:

之间搜索文字
  1. 使用字符串函数搜索
  2. Regex
  3. 版本1

    基于您的解决方案的正则表达式版本     \d\d\/\d\d\/\d\d,\s\d{1,2}:\d\d(\s\w\w)\s-\s(.+?): ((.*)(\n)*(.*))+在这种情况下,第二组将具有名称或电话号码 请注意date的前向版本已在此版本中转义,因此您可能需要对其进行更改

    版本2

    :.+?-\s(.+?):-:之间搜索文本,第一组将保留namephonenumber。假设上面提到message format

    版本2 +

    :[^-]+-\s([^:]+):-:之间搜索文本,第一组将保留namephonenumber。假设上面提到message format

    版本3

    :.+?-\s(.+?):(.+) first group - NameOrNumber 2nd group - 消息

    版本3 +

    :[^-]+-\s([^:]+):(.+) first group - NameOrNumber 2nd group - 消息

    版本4,假设编号以+开头而名称不是

    :[^-]+-\s([^:\+]*)(\+*[^:]+):(.+)

    • 第一组持有name(如果有)
    • 第二组将number开头的+(如果有)
    • 第3组持有message
    • online version 4 example

    第5版 - 消息的多行支持(基于日期的分隔符)

    (\d{2}\/\d{2}\/\d{2}),\s([^-]+)+-\s([^:\+]*)(\+*[^:]+):((.|\n(?!\d{2}\/\d{2}\/\d{2},[^-]+))+)

    • 第一组持有该日
    • 第二组持有时间
    • 第3组持有name(如果有)
    • 如果有number
    • ,第4组将+开头
    • 第5组持有message
    • 第6组在分隔符后保留字符 online version 5 example

    版本5如何工作?

    1. (\d{2}\/\d{2}\/\d{2})寻找dd\mm\yy格式
    2. ,\s([^-]+)+-\s查看应该在,之后和-
    3. 之前的时间
    4. ([^:\+]*)(\+*[^:]+):在下一个:之前查找文字。如果有+,那么如果没有名称
    5. ,则为数字
    6. ((.|\n(?!\d{2}\/\d{2}\/\d{2},[^-]+))+) - 棘手的部分。这很棘手,因为.找到任何char期望new line。那么这部分是做什么的呢?它搜索任何字符或{em>不后跟\n的{​​{1}}。简单来说,如果dd\mm\yy,<anything here> -以日期开头,则不会将其作为消息的一部分进行捕获。
    7. 注释

      new line允许非法日期,例如\d{2}\/\d{2}\/\d{2}。它可以阻止它,但99/99/99是一个大的its solution

      regex - 在,\s([^-]+)+-\s,之间搜索小时。这可以根据实际需要更加谨慎地完成。

答案 1 :(得分:0)

好。让我们使用regex101:https://regex101.com/r/qX0pQ2/1

我使用的模式是:

(\d{2}\/\d{2}\/\d{2}),\s(\d{1,2}:\d{2}(?:\s(?:AM|PM)))?\s-\s(.*):\s(.*)

这是什么意思? Regex101详细解释了它,但让我简要地强调一下这些变化。简单地说,使用.*作为名称和消息。它代表&#34; 任何字符,零到任意多个&#34;。如果是这种情况,您可以将其更改为.+以确保名称或消息不能为空。

我将\d\d内容缩写为\d{2},这是相同的。另外,/是正则表达式中具有特殊含义的字符;你需要通过在它前面添加\来逃避它,如果你只想匹配角色本身。在Java中,这个转义字符本身具有特殊含义(即在Java-Strings中转义)。因此,您需要在Java中转义转义字符。例如,这会导致\\/

但是我们如何在Java中实现它?这是一些代码:

Pattern pattern = Pattern.compile("(\\d{2}\\/\\d{2}\\/\\d{2}),\\s(\\d{1,2}:\\d{2}(?:\\s(?:AM|PM)))?\\s-\\s(.*):\\s(.*)");
Matcher matcher = pattern.match(inputText);

if (matcher.find()) {
    String date = matcher.group(1);
    String time = matcher.group(2);
    String name = matcher.group(3);
    String message = matcher.group(4);
    // Do something with this
}

还有一件事:(...)是一个捕获组。您可以使用matcher.group(X)访问匹配的内容。如果您想在不使用捕获组的情况下使用(...),则可以使用(?:...),就像我为AM,PM做的那样。

希望你明白一切,玩得开心。以下是模式文档:Pattern.html

答案 2 :(得分:0)

这将所有主要组件分成不同的捕获组:

(\d{2}\/\d{2}\/\d{2}),\s(\d{2}:\d{2}\s(?:AM|PM))\s-\s(.*):\s(.*)

第1组:MM / DD / YY

第2组:HH:MM AM / PM

第3组:发件人姓名或号码

第4组:讯息内容