提问人:Matt 提问时间:11/14/2023 最后编辑:Matt 更新时间:11/17/2023 访问量:52
正则表达式来匹配未用引号括起来的字符串,并忽略
Regex to match strings that aren't surrounded by quotes and ignores strings that are
问:
我正在尝试编写一个 Splunk 查询,我需要解析给出给 Windows 程序的命令行参数。具体来说,我正在尝试获取正在安装的软件包的名称。以下是一些数据示例:
/i "package\name" test
/i "package\name" "test"
/i "package\ name" test
/i "package\ name" "test"
/i package\name test
/package package\name "test"
包名称前面始终以“/i”或“/package”(它们可以是大写或小写)和一个空格(尽管有时没有空格)开头。包名称通常用引号引起来,但有时不是。如果它位于引号中,则可以包含空格。它后面通常跟着更多的命令行参数,有时用引号,有时不引号,但我并不真正关心这些。它们由字符串 test/“test” 表示。我基本上是在尝试获取“i”(或包)和包名称后面的命令行参数之间的所有内容。
我首先尝试使用将包名称提取到捕获组中。但问题是第三个和第四个测试字符串,因为引号中的空格。它们会导致它们之后的所有内容都被切断,所以我最终只会得到“包”而不是“包名称”。\/([iI]|(?i)package)\s?(?<package>.*?)\s
所以我想也许我可以使用一个正则表达式来提取引号内的所有内容,另一个正则表达式来提取没有引号的所有内容,然后将它们组合在一起。
使用以下正则表达式,我可以毫无问题地从上述前 4 个字符串中获取“package\name”或“package\name”:\/([iI]|(?i)package)\s?"(?<package1>.*?)"
为了获得最后 2 个,我尝试获取 i/package 之后不以引号开头的所有内容:\/([iI]|(?i)package)\s?[^"](?<package2>.*?)\s
但是,使用 regex101.com,它似乎与所有测试字符串的包名称匹配。它切断了最后 2 个字符中的第一个字符,所以我会有“ackage\name”。我不确定为什么会发生这两种情况。
如果可以用一个表达式提取我想要的内容,那将是首选解决方案。但是,能够从最后 2 个测试用例中提取包名称也可以。但是,如果这是解决方案,则捕获组之间不应有重叠。package1 应与测试字符串 1-4 中的包名称匹配,包 2 应与 5-6 匹配。
更新:
我很欣赏大家的回答。我从一位同事那里得到了一些帮助,我能够将其调整为我认为可行的解决方案。我想我会分享它,以防其他人发现它有帮助:(?i)(\/i)\s?(?:\"(?<package1>[^\"]*)\"|(?<package2>\S+))
答:
请尝试以下捕获模式。该值将位于组 2 中。
(?i)\/(?:i|package) ?(")?(.+?)(?(1)(?<!\\)"|\s)
我能够使用此正则表达式解析示例数据。它使用条件匹配来决定package_name字段是否应以引号或空格结尾。
\/(?:i|package)\s*(\\\")?(?<package_name>(?(1)[^\"]+|\S+))(\1)?
此 regex101 示例不区分大小写,对带引号的包名称使用一种模式,对不带引号的包名称使用另一种模式:
(?i)\/(?:i|package)(?:\s*"([^\\]+\\\s*.*?)"|\s+([^\\"]+\\.*?)\s)
评论
(?Ji)\/(i|package)\s*(?:"(?<package1>.*?)"|(?<package1>\S+))
(?i)
\/.+?\\\W*(?<pkg_name>\w+)