Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #14416 > unrolled thread
| Started by | galyle <galyle@gmail.com> |
|---|---|
| First post | 2011-10-10 14:57 -0700 |
| Last post | 2011-10-10 17:03 -0600 |
| Articles | 5 — 4 participants |
Back to article view | Back to comp.lang.python
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
| From | galyle <galyle@gmail.com> |
|---|---|
| Date | 2011-10-10 14:57 -0700 |
| Subject | Question: 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]
| From | MRAB <python@mrabarnett.plus.com> |
|---|---|
| Date | 2011-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]
| From | Vlastimil Brom <vlastimil.brom@gmail.com> |
|---|---|
| Date | 2011-10-11 00:59 +0200 |
| Subject | Re: 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]
| From | galyle <galyle@gmail.com> |
|---|---|
| Date | 2011-10-10 16:24 -0700 |
| Subject | Re: 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]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2011-10-10 17:03 -0600 |
| Subject | Re: 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