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.
CodePudding user response:
You can use forward lookaheads to assert that there are both a number and a letter within each set of parentheses:
\((?=[^)]*\d)(?=[^)]*[a-z])[^)] \)
The two lookaheads assert that there are some number of non-closing parenthesis characters and then a digit (first lookahead (?=[^)]*\d)
) or a letter (second lookahead (?=[^)]*[a-z])
). The [^)]
then matches the characters between the (
and )
.
In Javascript:
const str = '(5) (dogs) (5 dogs) (dogs 5)'
const regex = /\((?=[^)]*\d)(?=[^)]*[a-z])[^)] \)/ig
console.log(str.match(regex))
CodePudding user response:
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));