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)]*\dMatch 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));
