In this example...
(5) (dogs) (5 dogs) (dogs 5)
I would like to only match to...
(5 dogs) -or- (dogs 5)
The numbers could be any number of digits, contain commas, decimal points, math operators, dollar signs, etc. The only thing I need to pay attention to is that there are both numbers and alpha characters present.
I started with this modification of an example provided by hrs using this for the RegEx...
\(((letter).*(number))\)|((number).*(letter))\)
to only capture this...
(number letter) -or- (letter number)
but not...
(number) (letter)
by modifying the expression to be...
\(((^[a-zA-Z]).*(^[0-9]))\)|((^[0-9]).*(^[a-zA-Z]))\)
...but obviously I don't know what I'm doing.
You can use forward lookaheads to assert that there are both a number and a letter within each set of parentheses:
\((?=[^)\d]*\d)(?=[^)a-z]*[a-z])[^)]+\)
The two lookaheads assert that there are some number of non-closing parenthesis characters and then a digit (first lookahead (?=[^)\d]*\d)) or a letter (second lookahead (?=[^)a-z]*[a-z])). The [^)]+ then matches the characters between the ( and ).
In Javascript:
const str = '(5) (dogs) (5 dogs) (dogs 5)'
const regex = /\((?=[^)\d]*\d)(?=[^)a-z]*[a-z])[^)]+\)/ig
console.log(str.match(regex))
As an alternative with a single lookahead:
\((?=[^)a-z]*[a-z])[^\d)]*\d[^)]*\)
Explanation
\( Match ((?= Positive lookahead
[^)a-z]*[a-z] Match any char except ) or a-z, then match a-z) Close the lookahead[^\d)]*\d Match any char except a digit or ) and then match a digit[^)]* Match any char except )\) Match )const s = '(5) (dogs) (5 dogs) (dogs 5)';
const regex = /\((?=[^)a-z]*[a-z])[^\d)]*\d[^)]*\)/ig;
console.log(s.match(regex));