拆分字符串以获取除最后一个元素外的所有内容

3
这是我的操作手册。
---
- name: This is a hello-world example
  hosts: localhost
  vars:
    mystr: "I.To.Be.war"
  tasks:

    - name: Hi
      debug:
        msg: "{{ mystr.split('.') | first | trim }}"

输出:

I
trim 过滤器用于在变量末尾去除可能存在的 \r\n
然而,我希望有一个通用解决方案,该方案应该打印分隔符最后一个元素之前的所有内容,即:.
期望输出:
I.To.Be

注意:我不希望有像 "{{ mystr.split('.')[0][1][2] }}" 这样的解决方案,因为它在本质上不是通用的。
3个回答

4
  1. 使用map过滤器将trim过滤器应用于列表中的每个元素。
  2. 使用Python列表切片获取除最后一个元素外的所有元素。
  3. 将元素重新连接起来。
$ ansible localhost -m debug \
-a "msg={{ (mystr.split('.') | map('trim'))[:-1] | join('.') }}" \
-e "mystr=I.to.be.war"
localhost | SUCCESS => {
    "msg": "I.to.be"
}

或者,您可以使用正则表达式匹配字符串的第一部分。

$ ansible localhost -m debug \
-a 'msg={{ mystr | regex_replace("^(.*)\\.[^.]*$", "\\1") }}' \
-e "mystr=I.to.be.war"
localhost | SUCCESS => {
    "msg": "I.to.be"
}

2
感谢您分享如何测试它。 - Allan Wind

4

因为您的需求似乎是要获取不带扩展名的文件名,注意有一个额外的Jinja过滤器splitext专门用于此目的:

在此任务中,可以这样使用:

- debug:
    var: "'I.To.Be.war' | splitext | first | trim"

会给您想要的结果。

ok: [localhost] => 
  '''I.To.Be.war'' | splitext | first | trim': I.To.Be

尽管 filter splitext 实际上返回元组,比普通的 split 更加方便:

ok: [localhost] => 
  '''I.To.Be.war'' | splitext | trim': ('I.To.Be', '.war')

3
您可以使用Ansible的regex_replace()过滤器:
mystr | regex_replace('\\.[^.]+$', '')

分隔符如果使用 / 怎么样? - Ashar
regex_replace('/[^/]+$', '') - Allan Wind
2
@Ashar:请阅读SO用户需要付出多少努力。在评论中询问这种澄清问题,而您已经具有经验/声誉并且知道您已经在ansible标签上提出的问题数量非常接近于对您寻求帮助的人们的完全不尊重。 - Zeitounator
@Zeitounator 很抱歉,我忽略了另一篇帖子的解决方案,试图使用 / 而不是 .,显然这是不起作用的,所以我发布了评论。我已经能够在这里提出的解决方案上进行调整,以适应不同的分隔符。谢谢你的帮助。 - Ashar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接