【问题标题】:Regex: match string with previous match正则表达式:匹配字符串与前一个匹配
【发布时间】:2019-03-23 12:35:01
【问题描述】:

我正在努力解决这个正则表达式难题,但这超出了我的专业知识......

我有这样的字符串:

字符串 1:

Interface123|HostVienna ~ Tunnel22 ~ CustomerA ~ ServiceA  ~ Vienna, Street 10|HostAmsterdam ~ Interface123 ~ CustomerB ~ ServiceA  ~ Amsterdam, Street 40|HostSarajevo ~ Interface12 ~ CustomerC ~ ServiceA ~ Sarajevo, Street 1040

字符串 2

Interface123|HostAmsterdam ~ Interface123 ~ CustomerB ~ ServiceA  ~ Amsterdam,Street 40

我正在尝试制作一个可以匹配从字符串开头到“|”的所有内容的正则表达式(单词)并使用该匹配项我试图找到由“|”分隔的字符串包含那个词。在我的例子中,第一个词是Interface123

根据上述任一示例,结果应为:

HostAmsterdam ~ Interface123 ~ CustomerB ~ ServiceA  ~ Amsterdam,Street 40

纯正则表达式可以做到这一点吗?

【问题讨论】:

  • 你的解释和例子不一样。你说直到“|”但你的例子在它之后开始
  • 什么是正则表达式?
  • Grafana 需要这个,我认为它是 Perl_Compatible_Regular_Expressions
  • 请标记您的编程语言/环境。
  • 应该Interface123 匹配包含Interface1234 的行吗?

标签: regex pcre grafana


【解决方案1】:

这可以通过正则表达式反向引用实现,但并非每个实现都支持它们。比如:

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

第二组将捕获您需要的内容。

说明:^([^|]+)\| 捕获您的关键字,(?:[^|]*\|)*? 匹配零个或多个被'|' 包围的字符串,没有关键字,([^|]*\1[^|]*) 匹配您最终需要的。

Demo

【讨论】:

    【解决方案2】:

    /^([^|]+)\|(?:[^|]+\|)*?\K[^|]*\b\1\b[^|]*/

    在搜索下一次出现时,抓住针并至少使用单词边界非常重要。

    此外,启用匹配作为字符串中的第一个、中间或最后一个数据集也很重要。这就是(?:[^|]+\|)*?的重要性

    演示:https://regex101.com/r/7lMwZf/5

    细分:

    ^                     # start of string
    ([^|]+)\|             # capture needle then match first delimiting pipe
    (?:[^|]+\|)*?         # match zero or more "sets of data"
    \K[^|]*\b\1\b[^|]*    # forget previously matched characters with \K, then match set of data containing the needle until the end of string or first encountered pipe
    

    【讨论】:

      【解决方案3】:

      这是一个似乎有效的模式:

      (?<=\||^)((?:(?!\|).)*Interface123.*?)(?=\||$)
      

      这使用回火点来匹配您想要的字符串段,包含Interface123。以下是简要说明:

      (?<=\||^)       assert that what is prior is either pipe or the start of the string
      ((?:(?!\|).)*   consume anything so long is it is NOT pipe
      Interface123.*? match 'Interface123` followed by anything up to
      (?=\||$)        assert that what follows is either pipe or the end of the string
      

      Demo

      此答案使用环视,但根据您的评论,您的正则表达式风格与 Perl 兼容,这应该不是问题。

      【讨论】:

      • 需要匹配整个“段”对吗?所以它不匹配Interface1234
      • 我认为 OP 想先找到Interface123,然后再找到周围字符的第二次出现。目前还不清楚,但我很确定 OP 正在寻找的答案不会在实际的正则表达式中涉及 Interface123
      • 是的,你是对的,它可以是任何接口。正则表达式应该从字符串的开头到 "|ˇ
      • @Whit3H0rse 我仍然认为这里的最佳做法是使用 Perl 从文本中提取值 Interface123(这应该很容易做到)。一旦你缓存了那个值,然后使用我的答案作为模板构建你的正则表达式模式。
      • Grafana 只使用正则表达式,这就是我所拥有的。如果这是脚本,那么答案很简单
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-13
      • 2014-04-16
      • 1970-01-01
      • 1970-01-01
      • 2012-06-05
      • 2013-12-25
      相关资源
      最近更新 更多