Regex (Java) для поиска всех символов, которым предшествует четное число других символов - PullRequest
5 голосов
/ 06 января 2012

Я бы хотел управлять строкой в ​​Java с помощью Regex. Цель состоит в том, чтобы найти все $ знаки с четным числом \ перед ними (или ни одного), а затем добавить еще один \.

Пример:

"$ Find the $ to \$ escape \\$ or not \\\$ escape \\\\$ like here $"

должно привести к:

"\$ Find the \$ to \$ escape \\\$ or not \\\$ escape \\\\\$ like here \$"

Обоснование здесь: некоторые $ уже экранированы с помощью \, а некоторые escape \ могут быть в строке также в форме \\. Мне нужно сбежать от оставшихся $.

Ответы [ 2 ]

8 голосов
/ 06 января 2012

Это должно сделать работу: заменить:

(^|[^\\])(\\{2})*(?=\$)

со всем сопоставленным текстом (кроме заглядывания), затем следует \\.

Иллюстрация в Perl:

$ perl -pe 's,(^|[^\\])(\\{2})*(?=\$),$&\\,g'
"$ Find the $ to \$ escape \\$ or not \\\$ escape \\\\$ like here $" # in...
"\$ Find the \$ to \$ escape \\\$ or not \\\$ escape \\\\\$ like here \$" # out
"\$ Find the \$ to \$ escape \\\$ or not \\\$ escape \\\\\$ like here \$" # in...
"\$ Find the \$ to \$ escape \\\$ or not \\\$ escape \\\\\$ like here \$" # out

В Java полное совпадение текста - $0. Пример кода:

// package declaration skipped
import java.util.regex.Pattern;

public final class TestMatch
{
    private static final Pattern p
        = Pattern.compile("(^|[^\\\\])(\\\\{2})*(?=\\$)");

    public static void main(final String... args)
    {
        String input = "\"$ Find the $ to \\$ escape \\\\$ or not \\\\\\$ "
            + "escape \\\\\\\\$ like here $\"";

        System.out.println(input);

        // Apply a first time
        input = p.matcher(input).replaceAll("$0\\\\");
        System.out.println(input);

        // Apply a second time: the input should not be altered
        input = p.matcher(input).replaceAll("$0\\\\");
        System.out.println(input);
        System.exit(0);
    }
}

Выход:

"$ Find the $ to \$ escape \\$ or not \\\$ escape \\\\$ like here $"
"\$ Find the \$ to \$ escape \\\$ or not \\\$ escape \\\\\$ like here \$"
"\$ Find the \$ to \$ escape \\\$ or not \\\$ escape \\\\\$ like here \$"

Небольшое объяснение по поводу используемого регулярного выражения в следующем порядке:

                # begin regex:
(               # start group
    ^           # find the beginning of input,
    |           # or
    [^\\]       # one character which is not the backslash
)               # end group
                # followed by
(               # start group
    \\{2}       # exactly two backslashes
)               # end group
*               # zero or more times
                # and at that position,
(?=             # begin lookahead
    \$          # find a $
)               # end lookahead
                # end regex

Чтобы быть действительно полным, вот позиции, в которых движок регулярных выражений найдет соответствующий текст (обозначенный <>) и положение курсора (обозначенное |):

# Before first run:
|"$ Find the $ to \$ escape \\$ or not \\\$ escape \\\\$ like here $"
# First match
"<>|$ Find the $ to \$ escape \\$ or not \\\$ escape \\\\$ like here $"
# Second match
"$ Find the <>|$ to \$ escape \\$ or not \\\$ escape \\\\$ like here $"
# Third match
"$ Find the $ to \$ escape <\\>|$ or not \\\$ escape \\\\$ like here $"
# Fourth match
"$ Find the $ to \$ escape \\$ or not \\\$ escape <\\\\>|$ like here $"
# From now on, there is no match
0 голосов
/ 06 января 2012

Я думаю, что-то вроде этого может работать:

\$(\\\\)*\\
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...