1

I want to match:

  1. aaa
  2. aaa,bbb
  3. aaa,bbb,ccc

But not a list with a trailing comma. My current regex:

(\w{3},?)+

also matches lists with trailing commas (aaa,bbb,). I was thinking I could also do:

(\w{3})(,\w{3})*

but that is rather ugly. My real regex is not matching 3-letter-words, but something bigger, and repeating the regex is ugly. How can this be fixed?

  • 1
    Do you need tthe capturing group? – Panki Jun 13 '19 at 8:00
  • 1
    Is it full line matching? – dedowsdi Jun 13 '19 at 8:29
  • What you have is a decent solution to the problem. If you have a much bigger problem, state that – Inian Jun 13 '19 at 8:31
  • Capturing group is not needed. Yes full line matching. And repeating the BIG regex twice does not sound decent ;) – Karlo Jun 13 '19 at 8:47
  • 1
    I think a regex as simple as: [^,]$ answers the question as posted. If it doesn't what information would explain why it's not sufficient? – Hkoof Jun 13 '19 at 10:59
1

You can give a name to your big regex in PCRE like:

(?<big>[a-zA-Z0-9]+)

Everything after the ?<name> will be recorded with the name given.
Called Regular Expression Subroutines

So, repeats (?&name) become easy:

^(?<big>[a-zA-Z0-9]+)(,(?&big))*$

Test it Online

So, matching an IP, for example, becomes simpler:

^(?<ip>25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(.(?&ip)){3}$

Test it OnLine.

Use it with grep as:

grep -P '^(?<ip>25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(.(?&ip)){3}$'
0

The regex as simple as: [^,]$ answers the question.

Thanks to @Hkoof for their comment!

  • It answers the question in that it matches on those 3 samples and not on anything that ends in , but it would also match anything that ends in a character other than , like aaaa or a,,,,b... What about your big regexp? – Stéphane Chazelas Dec 3 '19 at 21:15
0

If using perl or PCRE regexps, you can avoid repetition by using things like (?1) to refer to the regexp in the first capture group:

grep -Px '(?:(\w{3}),)*(?1)'

Which would match on any non-empty comma separated list of 3 character words. Change to:

grep -Px '(?:(?:(\w{3}),)*(?1))?'

To allow an empty list.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.