Я заимствую довольно сложное регулярное выражение из некоторых реализаций PHP Textile (с открытым исходным кодом, должным образом приписанным) для простой, не полностью функциональной реализации Java, textile4j, которую я портирую на github и синхронизирую с Maven central ( оригинальный код был написан для предоставления плагина для blojsom, платформы блогов на Java; это часть больших усилий по обеспечению доступности зависимостей blojsom в Maven Central).
К сожалению, выражения регулярного выражения текстиля (хотя они работают в контексте preg_replace_callback
в PHP) завершаются ошибкой в Java со следующим исключением:
java.util.regex.PatternSyntaxException: Unclosed character class near index 217
Утверждение очевидно, решение неуловимо.
Вот необработанное многострочное регулярное выражение из реализации PHP:
return preg_replace_callback('/
(^|(?<=[\s>.\(])|[{[]) # $pre
" # start
(' . $this->c . ') # $atts
([^"]+?) # $text
(?:\(([^)]+?)\)(?="))? # $title
":
('.$this->urlch.'+?) # $url
(\/)? # $slash
([^\w\/;]*?) # $post
([\]}]|(?=\s|$|\)))
/x',callback,input);
Умно, я заставил текстильный класс "показать мне код", используемый в этом регулярном выражении, с простым echo
, что привело к следующему, довольно длинному регулярному выражению:
(^|(?<=[\s>.\(])|[{[])"((?:(?:\([^)]+\))|(?:\{[^}]+\})|(?:\[[^]]+\])|(?:\<(?!>)|(?<!<)\>|\<\>|\=|[()]+(?! )))*)([^"]+?)(?:\(([^)]+?)\)(?="))?":([\w"$\-_.+!*'(),";\/?:@=&%#{}|\^~\[\]`]+?)(\/)?([^\w\/;]*?)([\]}]|(?=\s|$|\)))
Я обнаружил пару возможных областей, которые могут привести к ошибкам синтаксического анализа, используя онлайн-инструменты, такие как RegExr от gskinner и RegexPlanet . Однако ни одна из этих подробностей не исправляет ошибку.
Я подозреваю , что есть проблема диапазона, скрытая в одном из классов символов, или где-то скрывается порядок Юникода, но я не могу его найти.
Есть идеи?
Мне также любопытно, почему PHP не выдает подобную ошибку, например, я обнаружил, что одно «пассивное подвыражение» плохо обрабатывается с помощью RegExr, но оно не исправляет исключение Java и не изменяет поведение в PHP, показанный ниже.
В #title
переключите сбежавшего парня:
(?:\(([^)]+?)\)(?="))? # $title
...^
(?:(\([^)]+?)\)(?="))? # $title
....^
Спасибо,
Тим
edit: добавление интерпретации Java String (с выходами) для регулярного выражения Textile, как определено RegexPlanet ...
"(^|(?<=[\\s>.\\(])|[{[])\"((?:(?:\\([^)]+\\))|(?:\\{[^}]+\\})|(?:\\[[^]]+\\])|(?:\\<(?!>)|(?<!<)\\>|\\<\\>|\\=|[()]+(?! )))*)([^\"]+?)(?:\\(([^)]+?)\\)(?=\"))?\":([\\w\"$\\-_.+!*'(),\";\\/?:@=&%#{}|\\^~\\[\\]`]+?)(\\/)?([^\\w\\/;]*?)([\\]}]|(?=\\s|$|\\)))"