获取所有字符,直到找到新的 date/hour

Get all the characters until a new date/hour is found

我要用正则表达式解析很多内容。 例如,内容可能是:

14-08-2015 14:18 : Example : Hello =) How are you?
What are you doing?
14-08-2015 14:19: Example2 : I'm fine thanks!

我有这个正则表达式,当然会 return 2 个匹配项,以及我需要的组 - 数据、小时、名称、多行消息:

(\d{2}-\d{2}-\d{4})\s?(\d{2}:\d{2})\s?:([^:]+):([^\d]+)

问题是,如果在消息中写入数字,这将无法正常进行,因为正则表达式将停止获取更多字符。 例如,在这种情况下,这将不起作用:

14-08-2015 14:18 : Example : Hello =) How are you?
What are you 2 doing?
14-08-2015 14:19: Example2 : I'm fine thanks!

如何在找到新的 date/hour 之前获取所有字符?

对日期使用前瞻性并获取该日期之前的所有内容。

/^(\d{2}-\d{2}-\d{4})\s?(\d{2}:\d{2})\s?:([^:]+):\s?((?:(?!^\d{2}-\d{2}-\d{4}\s?\d{2}:\d{2}).)*)/sm

我用两种方式编辑了你的正则表达式:

  1. 在前面添加了 ^,确保您只从他们自己的行上的时间戳开始,这应该会过滤掉大多数发布时间戳的人的问题

  2. 将最后一个捕获组替换为 ((?:(?!^\d{2}-\d{2}-\d{4}\s?\d{2}:\d{2}).)*)

    • (?!^\d{2}-\d{2}-\d{4}\s?\d{2}:\d{2}) 是一个否定的前瞻,日期
    • (?:(lookahead).)* 查找任意数量的字符,这些字符后面没有固定在行首的日期。
    • ((?:(lookahead).)*)就为你抓个群

效率不高,但很管用。注意 dotall 的 s 标志(点匹配换行符)和 m 标志让 ^ 在行首匹配。 ^ 在前瞻中是必要的,这样你就不会在有人发布时间戳的情况下停止匹配,并且在开始时确保你只匹配一行开头的日期。

演示:https://regex101.com/r/rX8eH0/3
在正则表达式中带有标志的演示:https://regex101.com/r/rX8eH0/4

问题出在您的最终捕获组 ([^\d]+)

您可以使用 ((?:(?!\d{2}-\d{2}-\d{4})[\s\S])+)

外括号:((?:(?!\d{2}-\d{2}-\d{4})[\s\S ])+)表示捕获组

下一组括号:((?:(?!\d{2}-\d{2}-\d{4})[\s\S])+) 表示我们要匹配1到无限次的非捕获组。

在内部我们有一个消极的展望:((?:(?!\d{2}-\d{2}-\d{4})[\s\S])+).这表示我们匹配的任何内容都不能包含日期。

我们实际捕获的是:((?:(?!\d{2}-\d{2}-\d{4})[\s\S])+) 表示我们捕获每个字符,包括换行符。

整个有效的正则表达式如下所示:

(\d{2}-\d{2}-\d{4})\s?(\d{2}:\d{2})\s?:([^:]+):((?:(?!\d{2}-\d{2}-\d{4})[\s\S])+)

https://regex101.com/r/wH5xR2/2