re.search - Pattern matching review

Matt Wheeler m at funkyhat.org
Sun May 29 13:02:46 EDT 2016


On 28 May 2016 at 19:12, Ganesh Pal <ganesh1pal at gmail.com> wrote:
> Dear Python friends,
>
> I am  on Python 2.7 and Linux . I am trying to extract the address
> "1,5,147456:8192" from the below stdout using re.search
>
> (Pdb) stdout
> 'linux-host-machine-1: Block Address for 1,5,27320320:8192 (block
> 1,5,147456:8192) --\nlinux-host-machine-1: magic
> 0xdeaff2fe         mark_cookie 0x300000000000000a\n'
> (Pdb) type(stdout)
> <type 'str'>
>
> Here is the code I have come up with, this looks buggy please review
> the same and suggest any better ways  to code the same
>
> the same may be splitlines() , re.complie() etc , my intention is to
> just match 1,5,147456:8192 and return the same.

This doesn't seem to exactly match your code below, i.e. your code is
attempting to construct a tuple from groups 1 through 4. To meet this
specification I could just `return re.search('(?<=\(block
)[^(]*(?=\))', stdout).group()`

> #Sample code
>
> import re
> import subprocess_run
>
> def get_block():

First point: your try block is too big. It should ideally contain just
the line that might raise the exception you're catching.

>     try:
>         cmd = "get_block_info -l"
>         # stdout is the output retrieved by subprocess.Popen()
>         stdout, stderr, exitcode = subprocess_run(cmd)
>         search_pat = 'Block Address.* \(block (\d+),(\d+),(\d+):(\d+)'
>         matched = re.search(search_pat, stdout)
>         block = (int(matched.group(1)),
>                    int(matched.group(2)),
>                    int(matched.group(3)),
>                    int(matched.group(4)),
>                   )

You could reduce repetition here by doing something like `tuple(int(n)
for n in matched.groups())`

>     except IOError, e:
>         logging.warning('Error reading lines from "%s" (%s).'
>                 % (cmd, e))
>
>     if block is None:
>        logging.error("block not found")

But this will never be reached, because when you try to get the groups
from `matched` above it will be None, so you'll get an AttributeError.
Consider revising (after moving the bulk of your code out of your
try/except block) to something like:

(run and re.search)
if matched:
    block = ....
    return block
else:
    logging.info("block not found")

>        return False
>     logging.info("block not found")
>     return block

And you probably don't need to explicitly return false, python
functions implicitly return None (which is falsey) if they don't reach
a return statement, but that's perhaps a matter of taste.

-- 
Matt Wheeler
http://funkyh.at



More information about the Python-list mailing list