提交 a70f1902 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Handle back-references in REGEXP_REPLACE() differently in Oracle mode

上级 cdaf7187
......@@ -119,6 +119,11 @@ public class Mode {
*/
public boolean logIsLogBase10;
/**
* The function REGEXP_REPLACE() uses \ for back-references.
*/
public boolean regexpReplaceBackslashReferences;
/**
* SERIAL and BIGSERIAL columns are not automatically primary keys.
*/
......@@ -255,6 +260,7 @@ public class Mode {
mode.convertOnlyToSmallerScale = true;
mode.uniqueIndexSingleNullExceptAllColumnsAreNull = true;
mode.treatEmptyStringsAsNull = true;
mode.regexpReplaceBackslashReferences = true;
mode.supportPoundSymbolForColumnNames = true;
// Oracle accepts keys of the form <namespace>.*. See
// https://docs.oracle.com/database/121/JJDBC/jdbcvers.htm#JJDBC29006
......
......@@ -1414,6 +1414,29 @@ public class Function extends Expression implements FunctionCall {
case REGEXP_REPLACE: {
String regexp = v1.getString();
String replacement = v2.getString();
if (database.getMode().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);
switch (c) {
case '$':
sb.append('\\');
break;
case '\\':
if (i + 1 < replacement.length()) {
c = replacement.charAt(i + 1);
if (c >= '0' && c <= '9') {
sb.append('$');
continue;
}
}
}
sb.append(c);
}
replacement = sb.toString();
}
}
String regexpMode = v3 == null || v3.getString() == null ? "" :
v3.getString();
int flags = makeRegexpFlags(regexpMode);
......
......@@ -17,3 +17,31 @@ select regexp_replace('Sylvain', 'S..', 'TOTO', 'mni') as X;
> --------
> TOTOvain
> rows: 1
set mode oracle;
select regexp_replace('first last', '(\w+) (\w+)', '\2 \1') as X from dual;
> X
> ----------
> last first
> rows: 1
select regexp_replace('first last', '(\w+) (\w+)', '$2 $1') as X from dual;
> X
> -----
> $2 $1
> rows: 1
set mode regular;
select regexp_replace('first last', '(\w+) (\w+)', '\2 \1') as X from dual;
> X
> ---
> 2 1
> rows: 1
select regexp_replace('first last', '(\w+) (\w+)', '$2 $1') as X from dual;
> X
> ----------
> last first
> rows: 1
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论