четверг, 13 марта 2014 г.

Java regexp как работать с мультизаменой в мульристрочности

Мульристрочность?
Чтобы работать с "мультистрочными"(большими и с переносом строк) String нужно при компилирование патерна включить следующие ключи:
Pattern pattern = Pattern.compile("some pattern", Pattern.MULTILINE | Pattern.DOTALL);

Как работают группы в regexp java?
Matcher m = pattern.matcher(str);
if(m.matchers()) {
  String g1 = m.group(); // тоже самое что и m.group(0) - оригинал переданной строки
  String g1 = m.group(1); // часть содержимого, что подошла под общий патерн, но только та, которая помечена первыми скобками () в патерне
  String g2 = m.group(2); // часть содержимого, что подошла под общий патерн, но только та, которая помечена вторыми скобками () в патерне
 // и так далее
}

Как обьединять Predefined Character Classes c символами которых в них не достает?
Вот пример один и больше символов "слов", плюс двоеточие(:):
[\\w:]
Пример один и больше символов "слов", плюс пробельные символы, плюс запятая, плюс знак минуса:
[\\w\\s,\\-]

Как подменить все совпадения, что подпадают под сложную регулярку с группами?
Наверно наш друг рекурсия, мы поочереди перебираем каждое совпадение, делаем магию и вызываем повторно метод.
Пример с реального проекта:
/**
 * Created by aieremenko on 3/11/14 3:12 PM
 */
@Service
@Order
public class FunctionProcessor extends WebcontentProcessor {
  private static final Logger log = LoggerFactory.getLogger(FunctionProcessor.class);

  /**
   * Example of function in webcontent [WEBCONTENT_FUNC:MATH:SUM{1, 2}]
   */
  private static final String WEBCONTENT_FUNCTION_FORMAT = "\\[WEBCONTENT_FUNC:([\\w:]+)\\{([\\w\\s,\\-]+)\\}\\]";
  private static final String WEBCONTENT_FUNCTION_FAILED_STUB = "~";

  private static final Pattern compiledWebcontentFunctionPattern = Pattern.compile("^(.*?)(" + WEBCONTENT_FUNCTION_FORMAT + ")(.*)$",
      Pattern.MULTILINE | Pattern.DOTALL);

  @InjectWebcontentFunctions
  private Map webcontentFunctions;

  @Override
  public JournalArticleDisplayWrapper process(JournalArticleDisplayWrapper jad) {
    jad.setContent(replaceFunctionsCallsByTheirReturns(jad.getContent()));
    return jad;
  }

  protected String replaceFunctionsCallsByTheirReturns(String content) {

    Matcher m = compiledWebcontentFunctionPattern.matcher(content);
    if (m.matches()) {
      String functionBody = m.group(2);
      String functionCmsName = m.group(3);
      String functionParams = m.group(4);

      String replacement = WEBCONTENT_FUNCTION_FAILED_STUB;

      if (webcontentFunctions.containsKey(functionCmsName)) {
        Function functionImpl = webcontentFunctions.get(functionCmsName);
        try {
          replacement = functionImpl.apply(functionParams);
        } catch (Exception e) {
          log.error(e.getMessage(), e);
        }
      }

      String contentWithReplacedFoundFunctionBody = content.replaceAll(
          escapeForRegexp(functionBody),
          replacement);
      return replaceFunctionsCallsByTheirReturns(contentWithReplacedFoundFunctionBody);
    }
    return content;
  }

  private String escapeForRegexp(String str) {
    return str.replaceAll("\\[", "\\\\[")
              .replaceAll("\\]", "\\\\]")
              .replaceAll("\\{", "\\\\{")
              .replaceAll("\\}", "\\\\}");
  }

}

Комментариев нет:

Отправить комментарий