Why doesn't Python's `re.split()` split on zero-length matches?

前端 未结 4 1874
别那么骄傲
别那么骄傲 2020-12-01 18:39

One particular quirk of the (otherwise quite powerful) re module in Python is that re.split() will never split a string on a zero-length match, for

相关标签:
4条回答
  • 2020-12-01 18:46

    Python supports this as of 3.7:

    >>> s = "You! Are you Tom? I am Danny."
    >>> re.split(r'(?<=[.!\?])', s)
    ['You!', ' Are you Tom?', ' I am Danny.', '']
    
    0 讨论(0)
  • 2020-12-01 18:49

    It's a design decision that was made, and could have gone either way. Tim Peters made this post to explain:

    For example, if you split "abc" by the pattern x*, what do you expect? The pattern matches (with length 0) at 4 places, but I bet most people would be surprised to get

    ['', 'a', 'b', 'c', '']

    back instead of (as they do get)

    ['abc']

    Some others disagree with him though. Guido van Rossum doesn't want it changed due to backwards compatibility issues. He did say:

    I'm okay with adding a flag to enable this behavior though.

    Edit:

    There is a workaround posted by Jan Burgy:

    >>> s = "Split along words, preserve punctuation!"
    >>> re.sub(r"\s+|\b", '\f', s).split('\f')
    ['', 'Split', 'along', 'words', ',', 'preserve', 'punctuation', '!']
    

    Where '\f' can be replaced by any unused character.

    0 讨论(0)
  • 2020-12-01 19:03

    To workaround this problem, you can use the VERSION1 mode of the regex package which makes split() produce zero-length matches as well:

    >>> import regex as re
    >>> re.split(r"\s+|\b", "Split along words, preserve punctuation!", flags=re.V1)
    ['', 'Split', 'along', 'words', ',', 'preserve', 'punctuation', '!']
    
    0 讨论(0)
  • 2020-12-01 19:03

    Basically, split() is two different functions into one. If you provide a parameter, it behaves very differently than when called without one.

    At first, it would seems that

    s.split() == s.split(' \t\n')
    

    but this is not the case, as you have shown. The doc says:

    [...] If sep is not specified or is None, any whitespace string is a separator and empty strings are removed from the result. [...]

    Even adding a 'remove_empty' parameter it would still behave weird, because the default of 'remove_empty' depends on the 'sep' parameter being there.

    0 讨论(0)
提交回复
热议问题