Соответствие регулярному выражению в Java - PullRequest
0 голосов
/ 18 марта 2012

У меня есть строка в Java, которую нужно разделить, используя "<$" и "$>" в качестве разделителей. Но если у меня есть что-то похожее на "\<$something_we_dont_care_what$>", тогда мы игнорируем это и идем дальше.

Я пытался написать регулярное выражение, делая это какое-то время, но продолжаю терпеть неудачу, и чтение регулярных выражений в Java только еще больше запутывает меня ...

Может кто-нибудь сказать мне правильный способ сделать это?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 18 марта 2012

Неважно. Я нашел решение после нескольких часов просмотра и экспериментов. Выражение Regex, которое делает именно то, что я хотел, выглядит следующим образом:

// char $ needs to be escaped because it has different meaning in regular expressions
// <$
String leftDelimiter = "(<\\$)";
// $>
String rightDelimiter = "(\\$>)";

// leftDelimiter | rightDelimiter
// when used to split a string would split it each time it detected those two patters
// and it would also split it in the case I dont want them to split it
// and that is "\<$foo$>" case - when they are "escaped" in the string

// to solve it we can try to match our leftDelimiter only if char \ isnt before it

// matches all [$ that dont start with \
String fixedLeftDelimiter = "(?<!\\\\)"+leftDelimiter;

// the problem presents itself with the rightDelimiter because it needs to check 
// whether there had been a leftDelimiter before it that has been escaped


// the following takes care of that

// matches all $> that dont have a <$ starting with \
String betterRightDelimiter = "(?<!\\\\"+leftDelimiter+whatCanBeInTags+rightDelimiter;

// whatCanBeInTags is everything that can be in out tags besides $ sign
// we are using {0,"+(Integer.MAX_VALUE-3)+"}? instead of *? because of a limitation
// of number of characters put in lookbehind assertion
String whatCanBeInTags = "[^\\$]{0,"+(Integer.MAX_VALUE-3)+"}?)";
0 голосов
/ 18 марта 2012

Думаю, у вас есть две строки - не в вашем коде, а для чтения из файла или JTextField:

s = "\<$foo$>";
p = "[^\\]?<\$[^\$]*\$>";

И вы хотите сопоставить шаблон со строкой.

Что я сделал до сих пор:

  • Группа, которая не содержит обратную косую черту [^\\]?, но может быть необязательной.
  • <$, где Доллар, как специальное регулярное выражение, должен маскироваться обратной косой чертой, как и обратная косая черта ранее.
  • Группа [^\$]*, в которой нет другого доллара свободной длины.
  • Доллар с \$> больше, чем. Опять же: доллар в маске.

Вопрос для вашего домена заключается в том, может ли foo-часть или что-то_we_dont_care_what содержать знак доллара, за которым не следует >. Я предположил, что нет.

  s.match (p);

Должен теперь возвращать true или false, но проблема в том, как вставить это в ваш код. Проблема в том, что не только регулярное выражение, но и сама Java обрабатывает обратную косую черту как маскирующий символ. Таким образом, вы должны удвоить каждый из них:

p = "[^\\\\]?<\\$[^\\$]*\\$>";

Если контрольный пример также является буквальным текстом в вашем коде, это относится и к нему:

"\\<$foo$>".matches (p);

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

public class PM
{
    public static void main (String args[])
    {
        String bad = "\\<$foo$>";
        String good = "<$foo$>";
        String p = "[^\\\\]?<\\$[^\\$]*\\$>";
        System.out.println ("bad:\t" + bad.matches (p));
        System.out.println ("good:\t" + good.matches (p));
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...