用于网页提取的正则表达式。积极的前瞻性问题
Regex for web extraction. Positive lookahead issues
下面是我正在使用的一些数据的示例。我已经阅读了很多涉及该主题的帖子,并在 regex101 上尝试了一段时间。
BotInfo[-]: Source IP:[10.1.1.100] Target Host:[CentOS70-1] Target OS:[CentOS
7.0] Description:[HTTP Connection Request] Details:[10.1.1.101 - - [28/May
/2013:12:24:08 +0000] "GET /math/html.mli HTTP/1.0" 404 3567 "-" "-" ] Phase:
[Access] Service:[WEB]
目标是有两个捕获组。一个用于标记(例如源 IP、目标主机、描述等),另一个用于最外层方括号中包含的内容。
是 "outermost" 让我明白了,因为 Details 标签的内容中有方括号。
这是我目前在上述正则表达式方面的进展。我正在使用 /g 标志:
\s?([^:]+):\[(.*?(?=\]\s.*?:\[))\]
这处理了除边缘情况之外的所有事情(它比需要的更复杂,因为我一直在尝试让边缘情况起作用)。
我当前的前瞻 (\]\s.*?:\[
) 在较高级别是匹配左括号结束,然后是下一个标记。另一个问题是这在最后一场比赛中失败了,因为没有以下标签。
编辑:请求成功输出的示例。使用提供的数据,目标是有两个捕获组产生这些对:
MATCH 1
1. `Source IP`
2. `10.1.1.100`
MATCH 2
1. `Target Host`
2. `CentOS70-1`
MATCH 3
1. `Target OS`
2. `CentOS 7.0`
MATCH 4
1. `Description`
2. `HTTP Connection Request`
MATCH 5
1. `Details`
2. `10.1.1.101 - - [28/May/2013:12:24:08 +0000] "GET /math/html.mli HTTP/1.0" 404 3567 "-" "-" `
MATCH 6
1. `Phase`
2. `Access`
MATCH 7
1. `Service`
2. `WEB`
深受this answer about nested patterns I end up with this regex with Demo here启发:
\s*([\w ]+):\s*(\[((?>[^[\]]+|(?2))*)\])
主要思想是尽可能重复匹配括号(如果找到左括号或右括号,则用(?2)重复。您要查找的数据实际上在第一个和第三个捕获组,第二个是用括号捕获以使递归正确发生。
关于正则表达式的详细信息:
\s*
匹配(并丢弃)字段 之前的所有 space
([\w ]+):
抓取字段名(都在:) 之前
\s*
再次丢弃字段 之前的任何 space
(\[
第二个捕获组的开始并匹配文字 [
((?>[^[\]]+
第三个捕获组的开始,具有原子匹配(阻止回溯以避免无限循环),除了括号
|(?2))
如果我们找到一个括号,尝试重新匹配整个第二组
*)
重复 0 次或无限次原子组与交替以获得嵌套括号并结束第三个捕获组
\])
我们要匹配的最后一个括号并结束用于原子匹配交替的第二个捕获组。
下面是我正在使用的一些数据的示例。我已经阅读了很多涉及该主题的帖子,并在 regex101 上尝试了一段时间。
BotInfo[-]: Source IP:[10.1.1.100] Target Host:[CentOS70-1] Target OS:[CentOS
7.0] Description:[HTTP Connection Request] Details:[10.1.1.101 - - [28/May
/2013:12:24:08 +0000] "GET /math/html.mli HTTP/1.0" 404 3567 "-" "-" ] Phase:
[Access] Service:[WEB]
目标是有两个捕获组。一个用于标记(例如源 IP、目标主机、描述等),另一个用于最外层方括号中包含的内容。
是 "outermost" 让我明白了,因为 Details 标签的内容中有方括号。
这是我目前在上述正则表达式方面的进展。我正在使用 /g 标志:
\s?([^:]+):\[(.*?(?=\]\s.*?:\[))\]
这处理了除边缘情况之外的所有事情(它比需要的更复杂,因为我一直在尝试让边缘情况起作用)。
我当前的前瞻 (\]\s.*?:\[
) 在较高级别是匹配左括号结束,然后是下一个标记。另一个问题是这在最后一场比赛中失败了,因为没有以下标签。
编辑:请求成功输出的示例。使用提供的数据,目标是有两个捕获组产生这些对:
MATCH 1
1. `Source IP`
2. `10.1.1.100`
MATCH 2
1. `Target Host`
2. `CentOS70-1`
MATCH 3
1. `Target OS`
2. `CentOS 7.0`
MATCH 4
1. `Description`
2. `HTTP Connection Request`
MATCH 5
1. `Details`
2. `10.1.1.101 - - [28/May/2013:12:24:08 +0000] "GET /math/html.mli HTTP/1.0" 404 3567 "-" "-" `
MATCH 6
1. `Phase`
2. `Access`
MATCH 7
1. `Service`
2. `WEB`
深受this answer about nested patterns I end up with this regex with Demo here启发:
\s*([\w ]+):\s*(\[((?>[^[\]]+|(?2))*)\])
主要思想是尽可能重复匹配括号(如果找到左括号或右括号,则用(?2)重复。您要查找的数据实际上在第一个和第三个捕获组,第二个是用括号捕获以使递归正确发生。
关于正则表达式的详细信息:
\s*
匹配(并丢弃)字段 之前的所有 space
([\w ]+):
抓取字段名(都在:) 之前
\s*
再次丢弃字段 之前的任何 space
(\[
第二个捕获组的开始并匹配文字[
((?>[^[\]]+
第三个捕获组的开始,具有原子匹配(阻止回溯以避免无限循环),除了括号|(?2))
如果我们找到一个括号,尝试重新匹配整个第二组*)
重复 0 次或无限次原子组与交替以获得嵌套括号并结束第三个捕获组\])
我们要匹配的最后一个括号并结束用于原子匹配交替的第二个捕获组。