Regex 正则表达式独立于订单和可用性匹配数据

Regex 正则表达式独立于订单和可用性匹配数据,regex,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 | 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*\|
\\\\\s*(?=[^\\\\]*端点=(?\w+)(?=[^\\\\]*事务ID=(?[\w-]+)(?=[^\\\]*用户ID=(?[\w-]+).\s*\|
但这需要我让所有的人都在场比赛。有没有办法只匹配内部可用的数据?如果其中一些或全部缺失,我希望正则表达式通过。如果数据在那里,我希望它在特定的正则表达式组中。

如果使用带查找条件的正则表达式,则可以在将文本匹配到组之前检查查找是否成功

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

[^|]+\|[^|]+\|\s*(?(?=[^\|]*endpoint=)(?=[^\|]*endpoint=(?<endpoint>\w+)))(?(?=[^\|]*transactionId=)(?=[^\|]*transactionId=(?<transactionId>[\w-]+)))(?(?=[^\|]*userId=)(?=[^\|]*userId=(?<userId>[\w-]+))).*\s*\|
[^\\]+\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*端点=(?=[^\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*\|
检查此示例:

如果将regex conditional与look around一起使用,则可以在将文本匹配到组之前检查look around是否成功

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

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

检查此示例:

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

然后使用您可以引用的命名捕获组来检查存在哪些值

(?:\G(?!^)|[^|]+\|[^|]+\|)\s*(?:transactionId=(?<transactionId>[\w-]+)|endpoint=(?<endpoint>\w+)|userId=(?<userId>[\w-]+)),?
(?:\G(?!^)[^ |]+\\\\[^ |]+\\\\\)\s*(?:事务ID=(?[\w-]+)|端点=(?\w+);用户ID=(?[\w-]+),?
解释

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

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

然后使用您可以引用的命名捕获组来检查存在哪些值

(?:\G(?!^)|[^|]+\|[^|]+\|)\s*(?:transactionId=(?<transactionId>[\w-]+)|endpoint=(?<endpoint>\w+)|userId=(?<userId>[\w-]+)),?
(?:\G(?!^)[^ |]+\\\\[^ |]+\\\\\)\s*(?:事务ID=(?[\w-]+)|端点=(?\w+);用户ID=(?[\w-]+),?
解释

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

您使用的语言/工具是什么?它们是否总是显示在第三个位置,按
|
分隔?在这种情况下,您可以编写正则表达式以仅匹配第三列,它们将由fluent位解析。是的,我可以匹配第三列,但我需要的是按匹配组排序的数据,而不是整个字符串。您使用的语言/工具是什么?它们是否总是以
|
分隔显示在第三个位置?在这种情况下,您可以编写正则表达式以仅匹配第三列,它们将由fluent位解析。是的,我可以匹配第三列,但我需要的是按匹配组排序的数据,而不是整个字符串。我不知道这种形式。也可以通过“简单”的头像和可选的非捕获组来实现:。谢谢@PJProudhon,这比我的回答要简单得多。我不知道这种形式。也可以通过“简单”的头像和可选的非捕获组来实现:。谢谢@PJProudhon,这比我的回答简单得多。谢谢,它起作用了,但我不确定我是否完全理解它。我也会尝试更深入地探讨这个解决方案:)谢谢,它正在工作,但我不确定我是否完全理解它。我还将尝试深入探讨该解决方案:)