Java 使用正则表达式读取聊天信息

Java 使用正则表达式读取聊天信息,java,regex,Java,Regex,我使用Java中的正则表达式从文本文件中读取消息内容,其中每个对话的格式如下: 2016年5月2日,上午12:05-‪+910058000000:你好 2016年5月2日,上午12:06-‪罗斯·克拉克‬: 你好 我形成了以下模式: \d\d/\d\d/\d\d\d{1,2}:\d\d(\s\w\w)?\s-\s((\w+\s?\w+)|(\+\d{2}\s\d{5}\s\d{5})):(((.*)(\n)*(.*)+ 问题是,输出显示了具有发件人名称的聊天,例如,在上面的聊天示例中,“Ross

我使用Java中的正则表达式从文本文件中读取消息内容,其中每个对话的格式如下:

2016年5月2日,上午12:05-‪+910058000000:你好

2016年5月2日,上午12:06-‪罗斯·克拉克‬: 你好

我形成了以下模式:
\d\d/\d\d/\d\d\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的消息不匹配。然而,也有一些罕见的情况下,一些消息与数字匹配

请帮帮我,我是新手


编辑:我想知道发件人何时是姓名或号码,也就是说,我想让一个组捕捉到姓名,另一个组捕捉到号码,这样我就可以进行区分。

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

 <Date>, <Time> - ‪<NameOrNumber>‬: <Message>
,-‪‬: 
然后,您可以在
-
之间搜索文本

  • 使用字符串函数进行搜索
  • 正则表达式
  • 版本1 基于您的解决方案的Regex版本
    \d\d\/\d\d\/\d\d\s\d{1,2}:\d\d(\s\w\w)\s-\s(+?):((.*)(\n)*(.*)+
    在这种情况下,第二组将具有名称或电话号码 请注意,
    date
    的前斜杠在此版本中转义,因此您可能需要更改它

    版本2
    :.+?-\s(+?):
    搜索介于
    -
    之间的文本:
    第一组将保存
    名称或
    电话号码。假设采用上述
    消息格式

    版本2+
    :[^-]+-\s([^:]+):
    搜索介于
    -
    之间的文本:
    第一组将保存
    名称或
    电话号码。假设采用上述
    消息格式

    版本3
    :.+?-\s(+?):(.+)
    第一组
    -名称或编号
    第二组
    -消息

    版本3+
    :[^-]+-\s([^:]+):(.+)
    第一组
    -名称或编号
    第二组
    -消息

    版本4,假设数字以
    +
    开头,而名称不以
    :[^-]+-\s([^:\+]*)(\+*[^::]+):(.+)

    • 第一组保存
      名称
      (如果有)
    • 第二组持有以
      +
      开头的
      编号(如有)
    • 第三组保存
      消息
    版本5-消息的多行支持(基于日期的分隔符)
    (\d{2}\/\d{2}\/\d{2}),\s([^-]+)+-\s([^:\+]*)(\+*[^:::]+):((.\n(?!\d{2}\/\d{2}\/\d{2},[^-]+)+)

    • 第一组举行这一天
    • 第二组举行时间
    • 第三组持有
      名称
      (如有)
    • 第四组持有以
      +
      开头的
      编号(如有)
    • 第五组持有
      信息
    • 第6组保存分隔符后的字符
    版本5是如何工作的?
  • (\d{2}\/\d{2}\/\d{2})
    查找
    dd\mm\yy
    格式
  • ,\s([^-]+)+-\s
    查找应该在
    之后和
    -
    之前的时间
  • ([^:\+]*)(\+*[^:]+):
    在下一个
    之前查找文本。如果有
    +
    ,那么如果没有,那么它就是一个数字,而不是一个名称
  • ((.|\n(?!\d{2}\/\d{2}\/\d{2},[^-]+)+)
    -棘手的部分。这是一个棘手的问题,因为
    查找除
    新行之外的任何字符。那么这部分做什么呢?它搜索任何未后跟
    dd\mm\yy,-
    的字符或
    \n
    。简单地说,如果
    新行
    以日期开始,它不会将其作为消息的一部分捕获
  • 笔记
    \d{2}\/\d{2}\/\d{2}
    允许像
    99/99/99
    这样的非法日期。可以防止它,但它的解决方案是一个非常大的正则表达式


    ,\s([^-]+)+-\s
    -此搜索时间假定介于
    -
    之间。这可以根据实际需要更仔细地完成。

    好的。让我们使用regex101进行以下操作:

    我使用的模式是:

    (\d{2}\/\d{2}\/\d{2}),\s(\d{1,2}:\d{2}(?:\s(?:AM|PM)))?\s-\s(.*):\s(.*)
    
    这是什么意思?Regex101对此进行了详细解释,但让我简要强调一下这些更改。简单地说,使用
    *
    作为名称和消息。它代表“任意字符,从零到任意多”。您可以将其更改为
    +
    ,以确保名称或消息不能为空(如果是这种情况)

    我用
    \d{2}
    缩写了你的
    \d\d
    东西,这是一样的。另外,as
    /
    是正则表达式中具有特殊含义的字符;如果您只想匹配字符本身,则需要通过在其前面添加一个
    \
    来对其进行转义。在Java中,这个转义字符本身有一个特殊的含义(即转义Java字符串中的内容)。因此,您需要在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之类的东西所做的那样


    希望你能理解一切,玩得开心。以下是模式文档:

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

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

    第一组:年月日

    第2组:HH:MM上午/下午

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

    第4组:在您的示例中,第3组消息的内容与
    (AM | PM)
    相匹配。您可以将其更改为
    (?:AM | PM)
    ,以表示不可用