逗号分隔的前缀列表,里面有逗号

Comma separated prefix list with commas inside

我正在尝试将逗号分隔的列表与包含逗号的前缀值相匹配。

我终于让它匹配所有没有 , 的事件。

示例字符串(使用 NL 进行可视化 - 原始字符串没有 NL):

field01=Value 1,
field02=Value 2,
field03=<xml value>,
field04=127.0.0.1,
field05=User-Agent: curl/7.28.0\r\nHost: example.org\r\nAccept: */*,
field06=Location, Resource,
field07={Item 1},{Item 2}

我的实际 RegEx 看起来像这个未优化的片段....

(?'fields'(field[0-9]{2,3})=?([\s\w\d_<>.:="*?\-\/\(){}<>'#]+))([^,](?&fields))*

有人知道如何解决这个问题吗?

编辑:

第一个模式接近我的预期结果。

这是字符串的匿名完整示例:

asm01=Predictable Resource Location,Information Leakage,asm02=N/A,asm04=Uncategorized,asm08=2021-02-15 09:18:16,asm09=127.0.0.1,asm10=443,asm11=N/A,asm15=,asm16=DE,asm17=User-Agent: curl/7.29.0\r\nHost: dev.example.com\r\nAccept: */*\r\nX-Forwarded-For: 127.0.0.1\r\n\r\n,asm18=/Common/_www.example.com_live_v1,asm20=127.0.0.1,asm22=,asm27=HEAD,asm34=/Common/_www.example.com_live_v1,asm35=HTTPS,asm39=blocked,asm41=0,asm42=3,asm43=0,asm44=Error,asm46=200000028,200100015,asm47=Unix hidden (dot-file) access,.htaccess access,asm48={Unix/Linux Signatures},{Apache/NCSA HTTP Server Signatures},asm50=40622,asm52=200000028,asm53=Unix hidden (dot-file) access,asm54={Unix/Linux Signatures},asm55=,asm61=,asm62=,asm63=8985143867830069446,asm64=example-waf.example.com,asm65=/.htaccess,asm67=Attack signature detected,asm68=<?xml version='1.0' encoding='UTF-8'?><BAD_MSG><violation_masks><block>13020008202d8a-f803000000000000</block><alarm>417020008202f8a-f803000000000000</alarm><learn>13000008202f8a-f800000000000000</learn><staging>200000-0</staging></violation_masks><request-violations><violation><viol_index>42</viol_index><viol_name>VIOL_ATTACK_SIGNATURE</viol_name><context>request</context><sig_data><sig_id>200000028</sig_id><blocking_mask>7</blocking_mask><kw_data><buffer>Ly5odGFjY2Vzcw==</buffer><offset>0</offset><length>2</length></kw_data></sig_data><sig_data><sig_id>200000028</sig_id><blocking_mask>4</blocking_mask><kw_data><buffer>Ly5odGFjY2Vzcw==</buffer><offset>0</offset><length>3</length></kw_data></sig_data><sig_data><sig_id>200100015</sig_id><blocking_mask>7</blocking_mask><kw_data><buffer>Ly5odGFjY2Vzcw==</buffer><offset>1</offset><length>9</length></kw_data></sig_data></violation></request-violations></BAD_MSG>,asm69=5,asm71=/Common/_dev.example.com_SSL,asm75=127.0.0.1,asm100=,asm101=HEAD /.htaccess HTTP/1.1\r\nUser-Agent: curl/7.29.0\r\nHost: dev.example.com\r\nAccept: */*\r\nX-Forwarded-For: 127.0.0.1\r\n\r\n#015

该模式不起作用,因为 fields 组匹配字符串 field

您正在尝试重复命名组 fields,但示例字符串中没有字符串 field

注意 [^,] 匹配除逗号以外的任何字符,您可以省略命名组 field 内的捕获组,因为它已经是一个组\w 也匹配 \d

有 2 个捕获组:

\b(asm[0-9]+)=(.*?)(?=,asm[0-9]+=|$)
  • \b一个单词边界
  • (asm[0-9]+) 捕获 组 1,匹配 asm 和 1+ 数字
  • =字面匹配
  • (.*?) 捕获 组 2,尽可能少地匹配任何字符
  • (?=正向前瞻,断言右边的是
    • ,asm[0-9]+= 匹配 ,asm 后跟 1+ 个数字和 =
    • |
    • $ 断言字符串结束
  • ) 关闭前瞻

Regex demo

一个简单的解决方案是(参见 regexr.com/5mg1b):

/((asm\d{2,3})=(.*?))(?=,asm|$)/g

匹配分组将是:

  • 组 #1 - asm01=可预测的资源位置,信息泄漏
  • 第 2 组 - asm01
  • 第 3 组 - 可预测的资源位置,信息泄漏

条件:

  • 这将匹配所有内容,包括空值

此处的关键是确保每个匹配项都由逗号和您的字段描述符或字符串结尾分隔。在这里展望未来会很方便:(?=,asm|$).