Validating a regex replacement string

A

Avshi

I'm trying to validate a replacement string during construction time,
but the only way I found is really ugly. Please let me know if there's
a better way.

Thank you,
Avshi Avital

This is how I do it:


/**
* Verifying the replacement string is a bit awkward,
* because the only way to do this is to run the
* replacement string on a text that the regex matches
* and see if an exception is thrown.
* We chit by counting the number of capturing groups
* in the regex and then creating a fake regex that
* contains that many capturing groups. Since we
* construct the (fake) regex, we can also produce a
* text that matches it.Running the replacement string
* on that text tests its validity.
*/
private void verifyReplacementString(Pattern, pattern,
String replacement)
{
int groupCount = pattern.matcher("").groupCount();
StringBuffer sb = new StringBuffer();
sb.append(".*");
for (int i = 0; i < groupCount; i++) {
sb.append("()");
}

// This should throw if the replacement is invalid.
try {
Pattern.compile(
sb.toString()).matcher("").replaceAll(replacement);
} catch (IndexOutOfBoundsException e) {
throw new IllegalStateException(
"Replacement string \""+replacement +
"\" is illegal for regex \"" +
pattern.pattern()+"\"");
}
}
 
A

Alan Moore

I'm trying to validate a replacement string during construction time,
but the only way I found is really ugly. Please let me know if there's
a better way.

Thank you,
Avshi Avital

This is how I do it:


/**
* Verifying the replacement string is a bit awkward,
* because the only way to do this is to run the
* replacement string on a text that the regex matches
* and see if an exception is thrown.
* We chit by counting the number of capturing groups
* in the regex and then creating a fake regex that
* contains that many capturing groups. Since we
* construct the (fake) regex, we can also produce a
* text that matches it.Running the replacement string
* on that text tests its validity.
*/
private void verifyReplacementString(Pattern, pattern,
String replacement)
{
int groupCount = pattern.matcher("").groupCount();
StringBuffer sb = new StringBuffer();
sb.append(".*");
for (int i = 0; i < groupCount; i++) {
sb.append("()");
}

// This should throw if the replacement is invalid.
try {
Pattern.compile(
sb.toString()).matcher("").replaceAll(replacement);
} catch (IndexOutOfBoundsException e) {
throw new IllegalStateException(
"Replacement string \""+replacement +
"\" is illegal for regex \"" +
pattern.pattern()+"\"");
}
}

The only other way I can see to do it is to parse the replacement
string looking for the largest $n group reference and compare it to
the groupCount() value. I prefer your way.
 
A

Avshi

Another reason that I did it the way I did is that while parsing the
replacement string you have to ignore escaped '$' and also pay
attention to escaped escapes ("\\")... It get's ugly.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,167
Latest member
SusanaSwan
Top