Getting captured group in one line

前端 未结 9 1032
既然无缘
既然无缘 2020-12-16 18:23

There is a known \"pattern\" to get the captured group value or an empty string if no match:

match = re.search(\'regex\', \'text\')
if match:
    value = mat         


        
相关标签:
9条回答
  • 2020-12-16 18:31

    One liners, one liners... Why can't you write it on 2 lines?

    getattr(re.search('regex', 'text'), 'group', lambda x: '')(1)
    

    Your second solution if fine. Make a function from it if you wish. My solution is for demonstrational purposes and it's in no way pythonic.

    0 讨论(0)
  • 2020-12-16 18:31

    Starting Python 3.8, and the introduction of assignment expressions (PEP 572) (:= operator), we can name the regex search expression pattern.search(text) in order to both check if there is a match (as pattern.search(text) returns either None or a re.Match object) and use it to extract the matching group:

    # pattern = re.compile(r'key=(\w+)')
    match.group(1) if (match := pattern.search('foo=bar,key=value,beer=pub')) else ''
    # 'value'
    match.group(1) if (match := pattern.search('no match here')) else ''
    # ''
    
    0 讨论(0)
  • 2020-12-16 18:36

    You can play with the pattern, using an empty alternative at the end of the string in the capture group:

    >>> re.search(r'((?<=key=)\w+|$)', 'foo=bar,key=value').group(1)
    'value'
    >>> re.search(r'((?<=key=)\w+|$)', 'no match here').group(1)
    ''
    
    0 讨论(0)
  • 2020-12-16 18:36

    One-line version:

    if re.findall(pattern,string): pass
    

    The issue here is that you want to prepare for multiple matches or ensure that your pattern only hits once. Expanded version:

    # matches is a list
    matches = re.findall(pattern,string)
    
    # condition on the list fails when list is empty
    if matches:
        pass
    

    So for your example "extract all alphanumeric characters (and _) from the text after the key= string":

    # Returns 
    def find_text(text):
        return re.findall("(?<=key=)[a-zA-Z0-9_]*",text)[0]
    
    0 讨论(0)
  • 2020-12-16 18:39

    You can do it as:

    value = re.search('regex', 'text').group(1) if re.search('regex', 'text') else ''
    

    Although it's not terribly efficient considering the fact that you run the regex twice.

    Or to run it only once as @Kevin suggested:

    value = (lambda match: match.group(1) if match else '')(re.search(regex,text))

    0 讨论(0)
  • 2020-12-16 18:41

    It's possible to refer to the result of a function call twice in a single one-liner: create a lambda expression and call the function in the arguments.

    value = (lambda match: match.group(1) if match else '')(re.search(regex,text))
    

    However, I don't consider this especially readable. Code responsibly - if you're going to write tricky code, leave a descriptive comment!

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