【问题标题】:Performing regex_findall and split() on the same line在同一行执行 regex_findall 和 split()
【发布时间】:2020-07-14 17:58:58
【问题描述】:

这是我要解析的输出:

hostname#show bgp vrf vrfname summary | i 1.1
BGP Route Distinguisher: 1.1.1.1:0
BGP router identifier 1.1.1.1, local AS number 2222
1.1.1.3      0 64512  349608  316062   896772    0    0     2w4d          1

我有以下正则表达式,它成功匹配最后一行。现在我需要分割那条线并查看最后一个索引。在这种情况下,它是“1”,但如果该值为“0”,我会想失败。

- name: debug test
  debug:
    msg: "{{show_bgp_sessions.data | regex_findall('\\d+\\.\\d+\\.\\d+\\.\\d+\\s\\s.*')}}"

我尝试在“msg”行的末尾添加几种不同格式的拆分,以便我可以在 failed_when 语句中获取最后一个索引来比较它:

msg: "{{show_bgp_sessions.data | regex_findall('\\d+\\.\\d+\\.\\d+\\.\\d+\\s\\s.*') | split(' ')}}"

但我收到以下错误消息:

 "template error while templating string: no filter named 'split'. String:

我还尝试使用几种不同形式的“ends_with”来验证字符串中的最后一个索引,因为我在 python 经验中经常使用它,但我无法让它在 ansible 中工作. 我无法创建新任务来解析数据并单独执行拆分,因为我需要通过循环运行此验证。

【问题讨论】:

  • 请分享代码。
  • 您能否使用捕获和匹配从 1 组开始的数字并以某种方式检查值? \d+\.\d+\.\d+\.\d+\s\s.*\b([1-9]\d*)$regex101.com/r/Xh66TK/1
  • 我试图沿着那条分组路线走下去,但无法让语法正常工作。根据您提供的链接,您上面的语法实际上与我正在寻找的最后一个值不匹配。它匹配整行,但我需要验证每一行的最后一个索引。
  • 它捕获第 1 组中的最后一个数字,以绿色突出显示。这是正确的值,不是吗?
  • 抱歉,我没有注意到我的屏幕上有眩光的绿色。这可能有效,让我在我的剧本中尝试一下。谢谢!

标签: regex split ansible


【解决方案1】:

选择行时,反转字符串,拆分第一项。例如

msg: "{{ (my_line|reverse).split()|first }}"

【讨论】:

  • 你是个救命恩人...我在任何地方都没有找到这个带括号的东西。供将来参考:输出:“{{ output | default([]) + [ ''.join( (item, (item.split('_')[0]).split('some_string') | last ) ) ] }}"
【解决方案2】:

可能@Thefourthbird 提供的正则表达式是更好的解决方案。

但是对于您手头的问题,这是由于 Jinja 中确实没有过滤器split 造成的,请参阅那里的列表:https://jinja.palletsprojects.com/en/2.11.x/templates/#list-of-builtin-filters

没有这个过滤器的原因很简单:split()是Python String的一个函数,而Jinja是Python,你可以直接使用它。

另外请注意,由于 regex_findall 用于多个匹配项,因此您必须选择列表的第一个元素,例如,使用过滤器 first

所以你的信息最终是:

msg: >-
  {{ 
    (
      show_bgp_sessions.data 
      | regex_findall('\\d+\\.\\d+\\.\\d+\\.\\d+\\s\\s.*') 
      | first
    ).split() 
  }}

鉴于剧本:

- hosts: all
  gather_facts: no
  vars:
    show_bgp_sessions:
      data: |
        hostname#show bgp vrf vrfname summary | i 1.1
        BGP Route Distinguisher: 1.1.1.1:0
        BGP router identifier 1.1.1.1, local AS number 2222
        1.1.1.3      0 64512  349608  316062   896772    0    0     2w4d          1
        
  tasks:
    - debug:
        msg: >-
          {{ 
            (
              show_bgp_sessions.data 
              | regex_findall('\\d+\\.\\d+\\.\\d+\\.\\d+\\s\\s.*') 
              | first
            ).split() 
          }}

回顾一下:

TASK [debug] ***************************************************************
ok: [localhost] => {
    "msg": [
        "1.1.1.3",
        "0",
        "64512",
        "349608",
        "316062",
        "896772",
        "0",
        "0",
        "2w4d",
        "1"
    ]
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-30
    • 2017-11-23
    • 2014-12-04
    • 2017-03-12
    • 1970-01-01
    • 2014-12-27
    • 2014-10-04
    • 2021-09-21
    相关资源
    最近更新 更多