正则表达式与订单和可用性无关地匹配数据

时间:2019-02-13 12:07:39

标签: regex

当某些请求或操作发生时,我有插入了可选请求数据的系统日志。

例如考虑以下日志条目

YYYY-MM-DDTHH:mm:ss PID | INFO | endpoint=SomeEndpoint, transactionId=12345, userId=67890 | Some log message

我要在这里用正则表达式解析的部分将是:

endpoint=SomeEndpoint, transactionId=12345, userId=67890

该附加数据可以按任何顺序排列,可能会丢失某些数据或将其完全丢失。 例如,所有这些都可以作为日志消息:

YYYY-MM-DDTHH:mm:ss PID | INFO | transactionId=12345, endpoint=SomeEndpoint, userId=67890 | Some log message
YYYY-MM-DDTHH:mm:ss PID | INFO | userId=67890, endpoint=SomeEndpoint | Some log message
YYYY-MM-DDTHH:mm:ss PID | INFO | transactionId=12345 | Some log message
YYYY-MM-DDTHH:mm:ss PID | INFO |  | Some log message

我设法像这样使用正向提前匹配来随机匹配它们:

\|\s*(?=[^\|]*endpoint=(?<endpoint>\w+))(?=[^\|]*transactionId=(?<transactionId>[\w-]+))(?=[^\|]*userId=(?<userId>[\w-]+)).*\s*\|

但这需要我让所有人都在那里进行比赛。有没有办法只匹配内部可用数据?如果某些缺少或全部丢失,我希望正则表达式通过。如果有数据,我希望在特定的正则表达式组中使用。

2 个答案:

答案 0 :(得分:2)

如果在条件范围内使用 regex有条件的正则表达式,则可以在将文本匹配到组中之前检查外观是否成功。

我更改了您的正则表达式以满足您的要求。

[^|]+\|[^|]+\|\s*(?(?=[^\|]*endpoint=)(?=[^\|]*endpoint=(?<endpoint>\w+)))(?(?=[^\|]*transactionId=)(?=[^\|]*transactionId=(?<transactionId>[\w-]+)))(?(?=[^\|]*userId=)(?=[^\|]*userId=(?<userId>[\w-]+))).*\s*\|

检查此示例:https://regex101.com/r/xAhXvw/1

答案 1 :(得分:2)

另一个选择可能是使用\G,它将在上一个匹配项的末尾或字符串的开头进行匹配。

然后使用您可以参考的命名捕获组来检查其中存在哪些值。

(?:\G(?!^)|[^|]+\|[^|]+\|)\s*(?:transactionId=(?<transactionId>[\w-]+)|endpoint=(?<endpoint>\w+)|userId=(?<userId>[\w-]+)),?

说明

  • (?:非捕获组
    • \G(?!^)断言上一场比赛的结束,如果不是开始的话
    • |
    • [^|]+\|[^|]+\|)\s*从开始比赛开始2次,而不是|,然后是|
    • (?:非capturiing组
      • transactionId=(?<transactionId>[\w-]+)匹配命名捕获组中的transactionId
      • |
      • endpoint=(?<endpoint>\w+)匹配命名捕获组中的端点
      • |
      • userId=(?<userId>[\w-]+匹配命名捕获组中的userId
    • )关闭群组
  • ),?关闭组并匹配可选的逗号

Regex demo