【问题标题】:How to use a specific stop-character for shlex.split?如何为 shlex.split 使用特定的停止字符?
【发布时间】:2021-01-14 16:44:06
【问题描述】:

如何告诉shlex,如果找到了;这个字符,那么,不要再分割任何东西了?

例子:

shlex.split("""hello "column number 2" foo ; bar baz""")  

应该给

["hello", "column number 2", "foo", "; bar baz"]

而不是["hello", "column number 2", "foo", ";", "bar", "baz"]


更一般地说,有没有办法用shlex 定义“评论”分隔符?即

shlex.split("""hello "column number 2" foo ;this is a comment; "last one" bye """)  

应该给

["hello", "column number 2", "foo", ";this is a comment;", "last one", "bye"]

【问题讨论】:

  • Shlex 允许您配置注释字符。但它不包括返回值中的 cmets。当它看到评论字符时它真的停止了;没有“两个cmets”这样的东西。如果一切正常,那就很简单了。
  • 哦,是的,没关系@rici,你是怎么做到的?
  • shlex 不应该是可配置的:它解析行的方式与符合 POSIX 的 shell 相同。
  • @chepner:那为什么它有这么多configuration options? (当然,部分原因是外壳不同)。

标签: python shlex


【解决方案1】:

shlex 解析器提供了一个用于指定注释字符的选项,但它在简化的shlex.split 界面中不可用。示例:

import shlex

a = 'hello "bla bla" ; this is a comment'

lex = shlex.shlex(a, posix=True)
lex.commenters = ';'
print(list(lex))  # ['hello', 'bla bla']

这里是一个稍微扩展的split函数,大部分是从Python标准库中复制过来的,对comments参数稍作修改,允许指定注释字符:

import shlex
def shlex_split(s, comments='', posix=True):
    """Split the string *s* using shell-like syntax."""
    if s is None:
        import warnings
        warnings.warn("Passing None for 's' to shlex.split() is deprecated.",
                      DeprecationWarning, stacklevel=2)
    lex = shlex.shlex(s, posix=posix)
    lex.whitespace_split = True
    if isinstance(comments, str):
        lex.commenters = comments
    elif not comments:
        lex.commenters = ''
    return list(lex)

您可能希望更改上述代码中comments 的默认值;正如所写,它与shlex.split 具有相同的默认值,即根本不识别cmets。 (shlex.shlex 创建的解析器对象默认使用# 作为注释字符,如果您指定comments=True,就会得到。我保留此行为是为了兼容。)

注意 cmets 被忽略;它们根本不会出现在结果向量中。当解析器遇到注释字符时,它会停止解析。 (所以永远不可能有两个 cmets。)comments 字符串是可能的 cmets 字符的列表,而不是注释序列。因此,如果您想将#; 都识别为注释字符,请指定comments='#:'

这是一个示例运行:

>>> # Default behaviour is the same as shlex.split
>>> shlex_split("""hello "column number 2" foo ; bar baz""") 
['hello', 'column number 2', 'foo', ';', 'bar', 'baz']
>>> # Supply a comments parameter to specify a comment character 
>>> shlex_split("""hello "column number 2" foo ; bar baz""", comments=';') 
['hello', 'column number 2', 'foo']
>>> shlex_split("""hello "column number 2" foo ;this is a comment; "last one" bye """, comments=';')
['hello', 'column number 2', 'foo']
>>> # The ; is recognised as a comment even if it is not preceded by whitespace.
>>> shlex_split("""hello "column number 2" foo;this is a comment; "last one" bye """, comments=';')
['hello', 'column number 2', 'foo']

【讨论】:

  • 谢谢@rici!在第一个例子中,你写了“它可用”,我想你想说“它在简化的拆分界面中可用”,我编辑修复,还有一个错字,我希望你没事。我还添加了一个非常简单的示例。
猜你喜欢
  • 2018-06-04
  • 2020-11-28
  • 1970-01-01
  • 2011-11-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-28
  • 1970-01-01
  • 2021-01-22
相关资源
最近更新 更多