Regex for checking if a string has mismatched parentheses?
Regex is not the right tool for the job. Scan a string manually.
Pseudo-code:
depth = 0
for character in some_string:
depth += character == '('
depth -= character == ')'
if depth < 0:
break
if depth != 0:
print "unmatched parentheses"
Regex to find unmatched parentheses
The short answer is that you can't find unmatched parentheses with regular expressions. Regular expressions encode regular languages, whereas the language of all properly matched parentheses is a context-free language.
Regular expression to match balanced parentheses
Regular expressions are the wrong tool for the job because you are dealing with nested structures, i.e. recursion.
But there is a simple algorithm to do this, which I described in more detail in this answer to a previous question. The gist is to write code which scans through the string keeping a counter of the open parentheses which have not yet been matched by a closing parenthesis. When that counter returns to zero, then you know you've reached the final closing parenthesis.
Regex to capture unpaired brackets or parentheses
Maybe,
\b\d+\)
might simply return the desired output, I guess.
Demo 1
Another way is to see what left boundary you might have, which in this case, I see digits, then what other chars we'd have prior to the closing curly bracket, and then we can design some other simple expression similar to:
\b\d[^)]*\)
Demo 2
Test
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegularExpression{
public static void main(String[] args){
final String regex = "\\b\\d[^)]*\\)";
final String string = "Programming is productive, (achieving a lot, and getting good results), it is often 1) demanding and 2) costly.\n\n"
+ "Programming is productive, (achieving a lot, and getting good results), it is often 1a b) demanding and 2a a) costly.\n\n\n"
+ "Programming is productive, (achieving a lot, and getting good results), it is often 1b) demanding and 2b) costly.\n\n"
+ "It is not supposed to match ( s s 1) \n";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
for (int i = 1; i <= matcher.groupCount(); i++) {
System.out.println("Group " + i + ": " + matcher.group(i));
}
}
}
}
Output
Full match: 1)
Full match: 2)
Full match: 1a b)
Full match: 2a a)
Full match: 1b)
Full match: 2b)
Full match: 1)
RegEx Circuit
jex.im visualizes regular expressions:
Using regex to detect ONLY double braces
You can simply exclude the braces from the "contained string" with a character class:
strings = re.findall(r'\{\{[^{}]*\}\}', string)
Missing parentheses with Regex
function isFine(str) {
return /[(){}\[\]]/.test( str ) &&
( str.match( /\(/g ) || '' ).length == ( str.match( /\)/g ) || '' ).length &&
( str.match( /\[/g ) || '' ).length == ( str.match( /]/g ) || '' ).length &&
( str.match( /{/g ) || '' ).length == ( str.match( /}/g ) || '' ).length;
}
Test
isFine('(this is fine and does not need attention)'); // true
isFine('This is also [fine]'); // true
isFine('This is bad( and needs to be edited'); // false
isFine('This [is (also) bad'); // false
isFine('as is this} bad'); // false
isFine('this string has no brackets but must also be considered'); // false
Note though, that this doesn't check bracket order, i.e. a)b(c
would be deemed fine.
For the record, here is a function that checks for missing brackets and checks that each type is correctly balanced. It doesn't allow a)b(c
, but it does allow (a[bc)d]
as each type is checked individually.
function checkBrackets( str ) {
var lb, rb, li, ri,
i = 0,
brkts = [ '(', ')', '{', '}', '[', ']' ];
while ( lb = brkts[ i++ ], rb = brkts[ i++ ] ) {
li = ri = 0;
while ( li = str.indexOf( lb, li ) + 1 ) {
if ( ( ri = str.indexOf( rb, ri ) + 1 ) < li ) {
return false;
}
}
if ( str.indexOf( rb, ri ) + 1 ) {
return false;
}
}
return true;
}
Finally, further to Christophe's post, here is what seems the best solution to checking for missing brackets and checking that all are correctly balanced and nested:
function checkBrackets( str ) {
var s;
str = str.replace( /[^{}[\]()]/g, '' );
while ( s != str ) {
s = str;
str = str.replace( /{}|\[]|\(\)/g, '' )
}
return !str;
};
checkBrackets( 'ab)cd(efg' ); // false
checkBrackets( '((a)[{{b}}]c)' ); // true
checkBrackets( 'ab[cd]efg' ); // true
checkBrackets( 'a(b[c)d]e' ); // false
Related Topics
How to Pass Arguments to My Function Through Add_Action
Proper Url Forming with a Query String and an Anchor Hashtag
Sqlstate[Hy000] [1698] Access Denied for User 'Root'@'Localhost'
How to Store an Array into MySQL
How to Check an Ip Address Is Within a Range of Two Ips in PHP
PHP Include Best Practices Question
How to Get All Class Names Inside a Particular Namespace
Manipulate a Url String by Adding Get Parameters
How to Send 500 Internal Server Error Error from a PHP Script
How to Preview an Image Before and After Upload
Android JSON Httpclient to Send Data to PHP Server with Httpresponse
Understanding MVC: Whats the Concept of "Fat" on Models, "Skinny" on Controllers
How to Convert a String to JSON Object in PHP
Clean Links to PHP-Generated JavaScript and CSS
How to Use Special Characters in Recipients Name When Using PHP's Mail Function