提交 77d5024d authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Extract Function.regexpReplace() with some minor changes

上级 05710fc2
...@@ -17,6 +17,7 @@ import java.sql.ResultSet; ...@@ -17,6 +17,7 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException; import java.util.regex.PatternSyntaxException;
...@@ -1350,50 +1351,11 @@ public class Function extends Expression implements FunctionCall { ...@@ -1350,50 +1351,11 @@ public class Function extends Expression implements FunctionCall {
break; break;
} }
case REGEXP_REPLACE: { case REGEXP_REPLACE: {
String input = v0.getString();
String regexp = v1.getString(); String regexp = v1.getString();
String replacement = v2.getString(); String replacement = v2.getString();
if (database.getMode().regexpReplaceBackslashReferences) { String regexpMode = v3 != null ? v3.getString() : null;
if ((replacement.indexOf('\\') >= 0) || (replacement.indexOf('$') >= 0)) { result = regexpReplace(input, regexp, replacement, regexpMode);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < replacement.length(); i++) {
char c = replacement.charAt(i);
if (c == '$') {
sb.append('\\');
} else if (c == '\\' && ++i < replacement.length()) {
c = replacement.charAt(i);
sb.append(c >= '0' && c <= '9' ? '$' : '\\');
}
sb.append(c);
}
replacement = sb.toString();
}
}
String regexpMode = v3 == null || v3.getString() == null ? "" :
v3.getString();
boolean isInPostgreSqlMode = Mode.ModeEnum.PostgreSQL.equals(database.getMode().getEnum());
int flags = makeRegexpFlags(regexpMode, isInPostgreSqlMode);
try {
if(isInPostgreSqlMode && !regexpMode.contains("g")) {
result = ValueString.get(
Pattern.compile(regexp, flags).matcher(v0.getString())
.replaceFirst(replacement),
database.getMode().treatEmptyStringsAsNull);
} else {
result = ValueString.get(
Pattern.compile(regexp, flags).matcher(v0.getString())
.replaceAll(replacement),
database.getMode().treatEmptyStringsAsNull);
}
} catch (StringIndexOutOfBoundsException e) {
throw DbException.get(
ErrorCode.LIKE_ESCAPE_ERROR_1, e, replacement);
} catch (PatternSyntaxException e) {
throw DbException.get(
ErrorCode.LIKE_ESCAPE_ERROR_1, e, regexp);
} catch (IllegalArgumentException e) {
throw DbException.get(
ErrorCode.LIKE_ESCAPE_ERROR_1, e, replacement);
}
break; break;
} }
case RPAD: case RPAD:
...@@ -1656,8 +1618,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -1656,8 +1618,7 @@ public class Function extends Expression implements FunctionCall {
break; break;
case REGEXP_LIKE: { case REGEXP_LIKE: {
String regexp = v1.getString(); String regexp = v1.getString();
String regexpMode = v2 == null || v2.getString() == null ? "" : String regexpMode = v2 != null ? v2.getString() : null;
v2.getString();
int flags = makeRegexpFlags(regexpMode, false); int flags = makeRegexpFlags(regexpMode, false);
try { try {
result = ValueBoolean.get(Pattern.compile(regexp, flags) result = ValueBoolean.get(Pattern.compile(regexp, flags)
...@@ -2040,6 +2001,40 @@ public class Function extends Expression implements FunctionCall { ...@@ -2040,6 +2001,40 @@ public class Function extends Expression implements FunctionCall {
return md; return md;
} }
private Value regexpReplace(String input, String regexp, String replacement, String regexpMode) {
Mode mode = database.getMode();
if (mode.regexpReplaceBackslashReferences) {
if ((replacement.indexOf('\\') >= 0) || (replacement.indexOf('$') >= 0)) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < replacement.length(); i++) {
char c = replacement.charAt(i);
if (c == '$') {
sb.append('\\');
} else if (c == '\\' && ++i < replacement.length()) {
c = replacement.charAt(i);
sb.append(c >= '0' && c <= '9' ? '$' : '\\');
}
sb.append(c);
}
replacement = sb.toString();
}
}
boolean isInPostgreSqlMode = Mode.ModeEnum.PostgreSQL.equals(mode.getEnum());
int flags = makeRegexpFlags(regexpMode, isInPostgreSqlMode);
try {
Matcher matcher = Pattern.compile(regexp, flags).matcher(input);
return ValueString.get(isInPostgreSqlMode && (regexpMode == null || regexpMode.indexOf('g') < 0) ?
matcher.replaceFirst(replacement) : matcher.replaceAll(replacement),
mode.treatEmptyStringsAsNull);
} catch (StringIndexOutOfBoundsException e) {
throw DbException.get(ErrorCode.LIKE_ESCAPE_ERROR_1, e, replacement);
} catch (PatternSyntaxException e) {
throw DbException.get(ErrorCode.LIKE_ESCAPE_ERROR_1, e, regexp);
} catch (IllegalArgumentException e) {
throw DbException.get(ErrorCode.LIKE_ESCAPE_ERROR_1, e, replacement);
}
}
private static int makeRegexpFlags(String stringFlags, boolean ignoreGlobalFlag) { private static int makeRegexpFlags(String stringFlags, boolean ignoreGlobalFlag) {
int flags = Pattern.UNICODE_CASE; int flags = Pattern.UNICODE_CASE;
if (stringFlags != null) { if (stringFlags != null) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论