Спасение от долларов

У меня возникли проблемы с выходом двойных долларов из строки, которая будет использоваться с шаблоном/сопоставителем функций регулярных выражений.

Это часть строки:

WHERE oid_2 = $$test$$ || oid_2 = $$test2$$

и это самый близкий код, который я пытался подобрать к решению:

List<String> strList = new ArrayList<String>();
Pattern pattern = Pattern.compile("\$\$.*?\$\$");
log.debug("PATTERN: "+pattern)
Matcher matcher = pattern.matcher(queryText);
while (matcher.find()) {
    strList.add(matcher.group());
}
log.debug(strList)

Это вывод отладки, который я получаю

- PATTERN: $$.*?$$
- []

Таким образом, шаблон на самом деле правильный, но заполнители не найдены в строке.

В качестве теста я попытался заменить «$$test$$» на «XXtestXX», и все работает отлично. Что мне не хватает? Я пробовал строки "/$", "\\", но до сих пор не нашел решения.


person GiLA3    schedule 12.04.2017    source источник
comment
См. ideone.com/Olm30x.   -  person Wiktor Stribiżew    schedule 12.04.2017
comment
\\$\\$.*?\\$\\$ говорит: недопустимый символ тела строки после знака доллара; решение: либо избегайте буквального знака доллара \$5, либо заключайте в скобки выражение значения ${5} @ строка 7, столбец 38. Pattern pattern = Pattern.compile(\\$\\$.*?\\$\\$) ^ 1 ошибка   -  person GiLA3    schedule 12.04.2017
comment
При использовании строки Slashy это работает! Большое спасибо, я был уверен, что пробовал это решение, но почему-то я этого не сделал, еще раз спасибо!   -  person GiLA3    schedule 12.04.2017
comment
Хорошо, сначала вам нужно экранировать доллар в строковом литерале с двойными кавычками, иначе будет предпринята попытка интерполяции.   -  person Wiktor Stribiżew    schedule 12.04.2017
comment
Мне не хватало того факта, что мне тоже приходилось спасаться от долларов косыми строками, я думаю, что это была проблема. Большое спасибо Виктор!   -  person GiLA3    schedule 12.04.2017


Ответы (2)


Обратите внимание, что $ в регулярном выражении соответствует концу строки. Чтобы использовать его в качестве буквального символа $, вам нужно экранировать его обратной косой чертой буквальный.

Вы использовали "\$\$.*?\$\$", который был переведен в литеральную строку, такую ​​​​как $$.*?$$, которая соответствует 2 позициям конца строки, любым 0+ символам как можно меньше, а затем снова 2 концам строк, что не имеет большого смысла. На самом деле вам понадобится обратная косая черта, чтобы сначала экранировать $, который используется в Groovy для вставки переменных в строковый литерал с двойными кавычками, а затем использовать 2 обратных косых черты, чтобы определить буквальную обратную косую черту - "\\\$\\\$.*?\\\$\\\$".

Однако, когда вы работаете с регулярными выражениями, строки с косой чертой весьма полезны, поскольку все, что вам нужно для экранирования специального символа, — это одна обратная косая черта.

Вот пример кода, извлекающий все совпадения из строки, имеющейся в Groovy:

def regex = /\$\$.*?\$\$/;
def s = 'WHERE oid_2 = $$test$$ || oid_2 = $$test2$$'
def m = s =~ regex
(0..<m.count).each { print m[it] + '\n' }

См. демонстрацию в Интернете.

person Wiktor Stribiżew    schedule 12.04.2017
comment
Что, если бы у меня была переменная для каждого заполнителя с тем же именем, как бы я заменил в ней значения? Например, у меня есть String test=1 и String test2=2. Как проще всего заменить все $$test$$ на 1 и все $$test2$$ на 2? Я надеюсь, что требование ясно - person GiLA3; 12.04.2017
comment
Вы имеете в виду, что вам нужно заменить переменные (по именам) их значениями? Не что-то подобное? - person Wiktor Stribiżew; 12.04.2017
comment
Если они у вас есть внутри строки, используйте что-то вроде этого. - person Wiktor Stribiżew; 12.04.2017
comment
Идея состоит в том, что у меня есть много запросов, которые я не могу редактировать, и у них есть $$placeholders$$, у меня есть каждый заполнитель в качестве входных данных в моем сценарии, и он имеет то же имя, что и $$placeholder$$. Например: входные переменные: тест, тест1, тест2. Мой запрос содержит $$test$$ $$test1$$, другой запрос может содержать $$test1$$ $$test1$$ $$test2$$ и т. д. - person GiLA3; 12.04.2017
comment
Готово, очень полезно! - person GiLA3; 13.04.2017

Любой, кто попадет сюда, может захотеть узнать другой ответ на этот вопрос, если вы хотите использовать косые строки Groovy:

myComparisonString ==~ /.*something costs [$]stuff.*/

Я не смог найти другого способа поместить $ в строку с косой чертой, по крайней мере, если за $ должен следовать текст. Если же, наоборот, за ним следует цифра (или, предположительно, любая небуква), это сработает:

myComparisonString ==~ /.*something costs \$100.*/

... проблема, конечно, в том, что "компилятор" GString (если это его имя) распознает "$stuff" как интерполированную переменную.

person mike rodent    schedule 18.04.2018