【问题标题】:PCRE Regex - Match everything to the first pipe not enclosed by square bracketsPCRE Regex - 将所有内容匹配到第一个不被方括号括起来的管道
【发布时间】:2017-07-18 11:19:05
【问题描述】:

我有以下文本行,我试图在其中提取所有内容,直到第一个未包含在方括号中的管道字符。

action=search sourcetype=audittrail [ localop | stats count | eval search_id = replace("$top10_drilldown_sid$", "^remote_[^_]*_", "") | table search_id ] [ localop | stats count | eval earliest = $top10_drilldown_earliest$ - 86400 | table earliest ] latest="$top10_drilldown_latest$" | stats values(savedsearch_name) AS search_name

预期输出:

action=search sourcetype=audittrail [ localop | stats count | eval search_id = replace("$top10_drilldown_sid$", "^remote_[^_]*_", "") | table search_id ] [ localop | stats count | eval earliest = $top10_drilldown_earliest$ - 86400 | table earliest ] latest="$top10_drilldown_latest$"

即除了尾随的| stats values(savedsearch_name) AS search_name

通过一些环视示例,我可以(几乎)使用 JavaScript 正则表达式得到我需要的东西

/.*\|(?![^\[]*\])/g - http://refiddle.com/refiddles/596dec4c75622d608f290000

但这并没有很好地转化为有效的 PCRE 兼容表达式(另外我想捕获所有内容,但不包括第一个管道)。

根据我的阅读,第一个括号集中的嵌套方括号可能是无法解决的复杂问题?在任何给定的集合中只会有一层嵌套括号(例如[..[]..][..[]..[]..]

我承认我不认为我已经完全了解正面和负面的环视,但任何帮助将不胜感激!

【问题讨论】:

  • 如果您确定括号是平衡的,请使用^(?:(\[(?:[^][]++|(?1))*])|[^|])+\K\|。但是,不必如此,您的字符串也可以包含\]
  • 感谢@WiktorStribiżew - 这对我来说有很多新概念。我会尽力解决它。查看您发送的示例,我意识到我没有包含我期望得到的内容。我现在就编辑它。
  • 感谢@WiktorStribiżew - 这很奏效!我不得不稍作调整才能抓住所有主角^(?<base_query>.*(?:(\[(?:[^][]++|(?1))*])|[^|])+)\|现在找到某种罗塞塔石碑来破译这个!我如何在此处为您提供信用/标记为已解决?
  • 好吧,如果你在开头添加.*,那会破坏逻辑。我的模式很容易阅读:匹配字符串的开头,然后匹配任何[...] 子字符串,里面平衡[...],或者| 以外的字符,整个重复1 次或多次。

标签: regex pcre


【解决方案1】:

在这种情况下,匹配所有不是分隔符的内容比尝试拆分更有效:

(?=[^|])[^][|]*(?:(\[[^][]*+(?:(?1)[^][]*)*+])[^][|]*)*

demo

详情:

(?=[^|]) # lookahead: ensure there's at least one non pipe character at the
         # current position, the goal is to avoid empty match.
[^][|]* # all that isn't a bracket or a pipe
(?:
    (  # open the capture group 1: describe a bracket part
        \[
         [^][]*+ # all that isn't a bracket (note that you don't have to care
                 # about of the pipe here, you are between brackets)
         (?:
             (?1)  # refer to the capture group 1 subpattern (it's a recursion
                   # since this reference is in the capture group 1 itself)
             [^][]* 
         )*+
         ]
    ) # close the capture group 1
    [^][|]*
)*

如果你也需要空的部分,你可以这样重写:

(?=[^|])[^][|]*(?:(\[[^][]*+(?:(?1)[^][]*)*+])[^][|]*)*|(?<=\|)

【讨论】:

  • 感谢您的精彩分析 - 我现在就试试看 :-)
  • @Arrjo:刷新页面,我打错了(现已更正)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多