Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #14416 > unrolled thread

Question: Optional Regular Expression Grouping

Started bygalyle <galyle@gmail.com>
First post2011-10-10 14:57 -0700
Last post2011-10-10 17:03 -0600
Articles 5 — 4 participants

Back to article view | Back to comp.lang.python


Contents

  Question:  Optional Regular Expression Grouping galyle <galyle@gmail.com> - 2011-10-10 14:57 -0700
    Re: Question:  Optional Regular Expression Grouping MRAB <python@mrabarnett.plus.com> - 2011-10-10 23:49 +0100
    Re: Question: Optional Regular Expression Grouping Vlastimil Brom <vlastimil.brom@gmail.com> - 2011-10-11 00:59 +0200
      Re: Question: Optional Regular Expression Grouping galyle <galyle@gmail.com> - 2011-10-10 16:24 -0700
    Re: Question: Optional Regular Expression Grouping Ian Kelly <ian.g.kelly@gmail.com> - 2011-10-10 17:03 -0600

#14416 — Question: Optional Regular Expression Grouping

Fromgalyle <galyle@gmail.com>
Date2011-10-10 14:57 -0700
SubjectQuestion: Optional Regular Expression Grouping
Message-ID<8537a563-69d7-4bce-b192-d9427aad0a7c@i14g2000yqg.googlegroups.com>
HI, I've looked through this forum, but I haven't been able to find a
resolution to the problem I'm having (maybe I didn't look hard enough
-- I have to believe this has come up before).  The problem is this:
I have a file which has 0, 2, or 3 groups that I'd like to record;
however, in the case of 3 groups, the third group is correctly
captured, but the first two groups get collapsed into just one group.
I'm sure that I'm missing something in the way I've constructed my
regular expression, but I can't figure out what's wrong.  Does anyone
have any suggestions?

The demo below showcases the problem I'm having:

import re

valid_line = re.compile('^\[(\S+)\]\[(\S+)\](?:\s+|\[(\S+)\])=|\s+[\d\
[\']+.*$')
line1 = "[field1][field2] = blarg"
line2 = "    'a continuation of blarg'"
line3 = "[field1][field2][field3] = blorg"

m = valid_line.match(line1)
print 'Expected: ' + m.group(1) + ', ' + m.group(2)
m = valid_line.match(line2)
print 'Expected: ' + str(m.group(1))
m = valid_line.match(line3)
print 'Uh-oh: ' + m.group(1) + ', ' + m.group(2)

[toc] | [next] | [standalone]


#14418

FromMRAB <python@mrabarnett.plus.com>
Date2011-10-10 23:49 +0100
Message-ID<mailman.1872.1318287022.27778.python-list@python.org>
In reply to#14416
On 10/10/2011 22:57, galyle wrote:
> HI, I've looked through this forum, but I haven't been able to find a
> resolution to the problem I'm having (maybe I didn't look hard enough
> -- I have to believe this has come up before).  The problem is this:
> I have a file which has 0, 2, or 3 groups that I'd like to record;
> however, in the case of 3 groups, the third group is correctly
> captured, but the first two groups get collapsed into just one group.
> I'm sure that I'm missing something in the way I've constructed my
> regular expression, but I can't figure out what's wrong.  Does anyone
> have any suggestions?
>
> The demo below showcases the problem I'm having:
>
> import re
>
> valid_line = re.compile('^\[(\S+)\]\[(\S+)\](?:\s+|\[(\S+)\])=|\s+[\d\
> [\']+.*$')
> line1 = "[field1][field2] = blarg"
> line2 = "    'a continuation of blarg'"
> line3 = "[field1][field2][field3] = blorg"
>
> m = valid_line.match(line1)
> print 'Expected: ' + m.group(1) + ', ' + m.group(2)
> m = valid_line.match(line2)
> print 'Expected: ' + str(m.group(1))
> m = valid_line.match(line3)
> print 'Uh-oh: ' + m.group(1) + ', ' + m.group(2)

Instead of "\S" I'd recommend using "[^\]]", or using a lazy repetition
"\S+?".

You'll also need to handle the space before the "=" in line3.

valid_line = 
re.compile(r'^\[(\[^\]]+)\]\[(\[^\]]+)\](?:\s+|\[(\[^\]]+)\])\s*=|\s+[\d\[\']+.*$')

[toc] | [prev] | [next] | [standalone]


#14419 — Re: Question: Optional Regular Expression Grouping

FromVlastimil Brom <vlastimil.brom@gmail.com>
Date2011-10-11 00:59 +0200
SubjectRe: Question: Optional Regular Expression Grouping
Message-ID<mailman.1873.1318287589.27778.python-list@python.org>
In reply to#14416
2011/10/10 galyle <galyle@gmail.com>:
> HI, I've looked through this forum, but I haven't been able to find a
> resolution to the problem I'm having (maybe I didn't look hard enough
> -- I have to believe this has come up before).  The problem is this:
> I have a file which has 0, 2, or 3 groups that I'd like to record;
> however, in the case of 3 groups, the third group is correctly
> captured, but the first two groups get collapsed into just one group.
> I'm sure that I'm missing something in the way I've constructed my
> regular expression, but I can't figure out what's wrong.  Does anyone
> have any suggestions?
>
> The demo below showcases the problem I'm having:
>
> import re
>
> valid_line = re.compile('^\[(\S+)\]\[(\S+)\](?:\s+|\[(\S+)\])=|\s+[\d\
> [\']+.*$')
> line1 = "[field1][field2] = blarg"
> line2 = "    'a continuation of blarg'"
> line3 = "[field1][field2][field3] = blorg"
>
> m = valid_line.match(line1)
> print 'Expected: ' + m.group(1) + ', ' + m.group(2)
> m = valid_line.match(line2)
> print 'Expected: ' + str(m.group(1))
> m = valid_line.match(line3)
> print 'Uh-oh: ' + m.group(1) + ', ' + m.group(2)
> --
> http://mail.python.org/mailman/listinfo/python-list
>

Hi,
I believe, the space before = is causing problems (or the pattern missing it);
you also need non greedy quantifiers +? to match as little as possible
as opposed to the greedy default:

valid_line = re.compile('^\[(\S+?)\]\[(\S+?)\](?:\s+|\[(\S+)\])\s*=|\s+[\d\[\']+.*$')

or you can use word-patterns explicitely excluding the closing ], like:

valid_line = re.compile('^\[([^\]]+)\]\[([^\]]+)\](?:\s+|\[([^\]]+)\])\s*=|\s+[\d\[\']+.*$')

hth
 vbr

[toc] | [prev] | [next] | [standalone]


#14421 — Re: Question: Optional Regular Expression Grouping

Fromgalyle <galyle@gmail.com>
Date2011-10-10 16:24 -0700
SubjectRe: Question: Optional Regular Expression Grouping
Message-ID<9e526b44-c0ba-48c2-8e21-66f54856fe7c@b6g2000vbz.googlegroups.com>
In reply to#14419
On Oct 10, 4:59 pm, Vlastimil Brom <vlastimil.b...@gmail.com> wrote:
> 2011/10/10 galyle <gal...@gmail.com>:
>
>
>
>
>
>
>
>
>
> > HI, I've looked through this forum, but I haven't been able to find a
> > resolution to the problem I'm having (maybe I didn't look hard enough
> > -- I have to believe this has come up before).  The problem is this:
> > I have a file which has 0, 2, or 3 groups that I'd like to record;
> > however, in the case of 3 groups, the third group is correctly
> > captured, but the first two groups get collapsed into just one group.
> > I'm sure that I'm missing something in the way I've constructed my
> > regular expression, but I can't figure out what's wrong.  Does anyone
> > have any suggestions?
>
> > The demo below showcases the problem I'm having:
>
> > import re
>
> > valid_line = re.compile('^\[(\S+)\]\[(\S+)\](?:\s+|\[(\S+)\])=|\s+[\d\
> > [\']+.*$')
> > line1 = "[field1][field2] = blarg"
> > line2 = "    'a continuation of blarg'"
> > line3 = "[field1][field2][field3] = blorg"
>
> > m = valid_line.match(line1)
> > print 'Expected: ' + m.group(1) + ', ' + m.group(2)
> > m = valid_line.match(line2)
> > print 'Expected: ' + str(m.group(1))
> > m = valid_line.match(line3)
> > print 'Uh-oh: ' + m.group(1) + ', ' + m.group(2)
> > --
> >http://mail.python.org/mailman/listinfo/python-list
>
> Hi,
> I believe, the space before = is causing problems (or the pattern missing it);
> you also need non greedy quantifiers +? to match as little as possible
> as opposed to the greedy default:
>
> valid_line = re.compile('^\[(\S+?)\]\[(\S+?)\](?:\s+|\[(\S+)\])\s*=|\s+[\d\[\']+.*$')
>
> or you can use word-patterns explicitely excluding the closing ], like:
>
> valid_line = re.compile('^\[([^\]]+)\]\[([^\]]+)\](?:\s+|\[([^\]]+)\])\s*=|\s+[\d\[\']+. *$')
>
> hth
>  vbr

Thanks, I had a feeling that greedy matching in my expression was
causing problem.  Your suggestion makes sense to me, and works quite
well.

[toc] | [prev] | [next] | [standalone]


#14420 — Re: Question: Optional Regular Expression Grouping

FromIan Kelly <ian.g.kelly@gmail.com>
Date2011-10-10 17:03 -0600
SubjectRe: Question: Optional Regular Expression Grouping
Message-ID<mailman.1874.1318287813.27778.python-list@python.org>
In reply to#14416
On Mon, Oct 10, 2011 at 4:49 PM, MRAB <python@mrabarnett.plus.com> wrote:
> Instead of "\S" I'd recommend using "[^\]]", or using a lazy repetition
> "\S+?".

Preferably the former.  The core problem is that the regex matches
ambiguously on the problem string.  Lazy repetition doesn't remove
that ambiguity; it merely attempts to make the module prefer the match
that you prefer.

Other notes to the OP:  Always use raw strings (r'') when writing
regex patterns, to make sure the backslashes are escape characters in
the pattern rather than in the string literal.

The '^foo|bar$' construct you're using is wonky.  I think you're
writing this to mean "match if the entire string is either 'foo' or
'bar'".  But what that actually matches is "anything that either
starts with 'foo' or ends with 'bar'".  The correct way to do the
former would be either '^foo$|^bar$' or '^(?:foo|bar)$'.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web