Справка по регулярным выражениям Java - PullRequest
1 голос
/ 08 февраля 2011

У меня есть строка, содержащая n подстрок в следующем формате, которому я хочу соответствовать:

{varName:param1, param2, param2}

Требования следующие:

  1. Только varName (внутри фигурныхскобки) является обязательным
  2. Нет ограничений на количество параметров
  3. Нет ограничений на пробелы внутри фигурных скобок, кроме имен переменных и параметров, которые не должны содержать пробелы

Я хотел бы иметь возможность захватывать varName и каждый из параметров в отдельности.

Я пришел к регулярному выражению, которое почти там, но не совсем.Любая помощь будет оценена.

Ответы [ 6 ]

2 голосов
/ 08 февраля 2011

Мне интересно, будет ли проще просто использовать String.split() разумно, а не сражаться с регулярными выражениями для вышеперечисленного.Разделители (двоеточия / пробелы / запятые) кажутся четко определенными.

1 голос
/ 08 февраля 2011
String s = "blah blah\n{varName:param1, param2, param2}\nblah";

Pattern p = Pattern.compile(
  "\\{([a-zA-Z]+)(?:\\s*:\\s*([^,\\s]+(?:\\s*,\\s*[^,\\s]+)*))\\}"
);
Matcher m = p.matcher(s);
if (m.find())
{
  String varName = m.group(1);
  String[] params = m.start(2) != -1
                  ? m.group(2).split("[,\\s]+")
                  : new String[0];

  System.out.printf("var: %s%n", varName);
  for (String param : params)
  {
    System.out.printf("param: %s%n", param);
  }
}

Если вы пытаетесь найти способ сопоставить строку и выделить все компоненты одним регулярным выражением, не беспокойтесь;это так хорошо, как может (если вы не переключитесь на Perl 6).Что касается производительности, я бы не беспокоился об этом, пока это не станет проблемой.

1 голос
/ 08 февраля 2011

Быстрое решение в psuedocode:

string.match(/{(\w+):([\w\s,]+)}/);
varName = matches[1];
params = matches[2].split(',');
1 голос
/ 08 февраля 2011

Как насчет регулярных выражений и сканера?

import java.util.Scanner;

public class Regex {

  public static void main(String[] args) {  
    String string = "{varName: param1, param2, param2}";   
    Scanner scanner = new Scanner(string);
    scanner.useDelimiter("[\\s{:,}]+");
    System.out.println("varName: " + scanner.next());
    while (scanner.hasNext()) {
      System.out.println("param: " + scanner.next());
    }
  }
}
0 голосов
/ 08 февраля 2011

Хорошо, у меня есть решение в регулярных выражениях, которое, кажется, работает нормально:

\ {\ s * ([^ \ {\}, \ s] +) \ s * (? :(? :: \ S * ([^ \ {\}, \ S] +) \ s *) (?: \ S * ([^ \ {\}, \ s] +) \ S *) *)?\}

Или даже притворяться, что способны понять это:

name = [^ \ {\}, \ s] +

ws = \ s*

\ {ws (имя) ws (?: (? :: ws (имя) ws) (?:, Ws (имя) ws) *)? \}

Я бы не сталНе рекомендую, но короткое тестирование, кажется, показывает, что это работает - хороший тизер для мозгов в 3 часа ночи;)

PS: Если вы сравниваете раздельное решение с этим или чем-то похожим, мне было бы интереснов слух, если бы были какие-либо различия в производительности - я не думаю, что регулярное выражение было бы особенно эффективным.

0 голосов
/ 08 февраля 2011

Опубликуйте, что у вас есть.Вы можете проверить это очень легко на этом сайте: http://www.regexplanet.com/simple/index.html

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