Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Match first group, second group or both in regex

I have the following regex:

   (electric|acoustic) (guitar|drums)

What I need is to match:

    electric guitar
    electric drums
    acoustic guitar
    acoustic drums
    electric 
    acoustic
    guitar 
    drums

I tried using the ? after both groups, but then it matched everything. Thanks!

Edit:

<script type="text/javascript">
 var s = "electric drums";

 if(s.match('^(?:electric()|acoustic())? ?(?:guitar()|drums())?(?:\1|\2|\3|\4)$')){
    document.write("match");
 } else {
    document.write("no match"); // returns this
 }
</script> 
like image 619
Kristian Avatar asked Dec 06 '12 11:12

Kristian


People also ask

How do I match a regex pattern?

To match a character having special meaning in regex, you need to use a escape sequence prefix with a backslash ( \ ). E.g., \. matches "." ; regex \+ matches "+" ; and regex \( matches "(" . You also need to use regex \\ to match "\" (back-slash).

What is matching group in regex?

Regular expressions allow us to not just match text but also to extract information for further processing. This is done by defining groups of characters and capturing them using the special parentheses ( and ) metacharacters. Any subpattern inside a pair of parentheses will be captured as a group.

What is the difference between a match and group in regex?

A Match is an object that indicates a particular regular expression matched (a portion of) the target text. A Group indicates a portion of a match, if the original regular expression contained group markers (basically a pattern in parentheses).

How do you group together in regular expressions?

By placing part of a regular expression inside round brackets or parentheses, you can group that part of the regular expression together. This allows you to apply a quantifier to the entire group or to restrict alternation to part of the regex. Only parentheses can be used for grouping.


2 Answers

One way would be to spell it out:

^((electric|acoustic) (guitar|drums)|(electric|acoustic|guitar|drums))$

or (because you don't need the capturing parentheses)

^(?:(?:electric|acoustic) (?:guitar|drums)|(?:electric|acoustic|guitar|drums))$

You can also use a trick if you don't like to repeat yourself:

^(?:electric()|acoustic())? ?(?:guitar()|drums())?(?:\1|\2|\3|\4)$

The (?:\1|\2|\3|\4) makes sure that at least one of the previous empty capturing groups (()) participated in the match.

like image 140
Tim Pietzcker Avatar answered Oct 10 '22 20:10

Tim Pietzcker


Use a lookahead based regex like this:

(?=.*?(?:electric|acoustic|guitar|drums))^(?:electric|acoustic|) ?(?:guitar|drums|)$

Live Demo

like image 33
anubhava Avatar answered Oct 10 '22 21:10

anubhava