5

I'm attempting to parse /etc/mtab but exclude /boot. I thought perhaps non-capturing groups would be the way to go, but it doesn't work as I expected. This is the regex I constructed:

proc = subprocess.Popen(["ssh", server, "cat", mtab],stdout = subprocess.PIPE)
for line in proc.stdout:
  fsMatch = re.search(r'([\w/:]+) (/([\w/:-]+)|(?:boot)) (nfs|ext3)', line)
  if fsMatch:
    print fsMatch.group(1,2,4)

Output:

('/dev/sda1', '/boot', 'ext3')
('/dev/mapper/foo1', '/export/foo1', 'ext3')
('/dev/mapper/foo2', '/export/foo2', 'ext3')
('/dev/mapper/foo3', '/export/foo3', 'ext3')
('/dev/mapper/foo4', '/export/foo4', 'ext3')
('/dev/mapper/foo5', '/export/foo5', 'ext3')
('servernfs:/install', '/mnt', 'nfs')

I'm pretty confident the | is wrong (and obviously more is wrong) but have hit a roadblock.

I'm looking for all matches for /[\w/:-]+ but exclude matches to /boot

Suggestions?

1
  • 3
    Regular expressions are not good at excluding things. Do it in a separate check. Commented Apr 4, 2013 at 6:01

2 Answers 2

6

You need to use a negative lookbehind or negative lookahead, described here with a hint below:

r'^(?!/boot).*$'

If you need to capture that 'servernfs:' one and not 'servernfs:/boot', you'll need to sprinkle in a little '|' and '([a-z]+:)' somewhere at the top (after the '^')

Sign up to request clarification or add additional context in comments.

Comments

1

Just exclude the line:

for line in proc.stdout:
  if 'boot' not in line:
      # the rest

However, since mtab is delimited on space, you can just use split:

>>> with open('foo.txt') as f:
...     lines = [line.split(' ') for line in f if 'boot' not in line]
...

3 Comments

It'd make more sense for that check to go on the if fsMatch line wouldn't it? eg:if fsMatch and not fsMatch.group(2).startswith('/boot') ?
Yea, the startswith is key. But then you've got the fs:/boot matching problem.
paths like /home/user/bin/reboot will be rejected by the 'boot' not in line filter, I think. And '/boot' doesn't fix it either without the startswith bit. I like Jon Clements approach. Let's the regex do the heavy lifting of a match and startswith does the simple, precise exclude.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.