смотреть вперед в кейт для шаблонов

Я работаю над составлением таблицы дел для юридической книги. Я преобразовал его в HTML, чтобы использовать теги для операций поиска и замены, и сейчас я работаю в Kate. В тексте указаны названия случаев, а ссылки на случаи приведены в сносках, например.

<i>Smith v Jones</i>127 ......... [other stuff including newline characters].......</br>127 (1937) 173 ER 406;

Я смог опережать работу в Кейт, используя:

<i>.*</i>([0-9]{1,4}) .+<br/>\1 .*<br/>

... но я столкнулся с проблемами жадности.

Текст в беспорядке, поэтому мне действительно нужно находить совпадения шаг за шагом, а не полагаться на пакетный процесс.

Существует ли текстовый редактор для Linux (или Windows), который поддерживает как опережающие, так и нежадные операторы, или мне придется попробовать grep или sed?


person user1489937    schedule 08.09.2012    source источник
comment
Я добавил форматирование кода, чтобы мы могли видеть теги, которые вы используете при поиске, но второй тег <br/>, кажется, отсутствует в образце текста, а первый на самом деле </br>/ в неправильном месте). Вы можете уточнить?   -  person Alan Moore    schedule 08.09.2012


Ответы (1)


Я не знаком с Кейт, но, похоже, он использует QRegExp, который несовместим с другими Perl-подобными вариантами регулярных выражений во многих важных отношениях. Например, большинство вариантов позволяют сделать отдельные квантификаторы нежадными, добавив вопросительный знак (например, .* => .+?), но в QRegExp вы можете сделать их только все жадными или все нежадными. Что еще хуже, похоже, что Кейт даже не позволяет вам это сделать — например, с помощью флажка Non-Greedy.

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

<i>[^<]*</i>(\d+)\b[^<]+<br/>\1\b[^<]*<br/>

Преимущество использования [^<]* вместо .* заключается в том, что он никогда не будет пытаться сопоставить что-либо после следующего <. .* всегда сначала захватывает остальную часть документа, но возвращается почти полностью к начальной точке. Нежадная версия, .*?, сначала будет соответствовать только следующему <, но если позже попытка сопоставления окажется неудачной, она продолжит работу и использует < и далее, в конечном счете, чтобы использовать весь документ.

Если могут быть другие теги, вместо них можно использовать [^<]*(<(?!br/>)[^<]*)*. Он будет потреблять любые символы, кроме < или <, если это не начало тега <br/>.

<i>[^<]*</i>(\d+)\b[^<]*(<(?!br/>)[^<]*)*<br/>\1\b[^<]*(<(?!br/>)[^<]*)*<br/>

Между прочим, то, что вы называете просмотром вперед (я предполагаю, что вы имеете в виду \1), на самом деле является обратной ссылкой. (?!br/>) в моем регулярном выражении является примером упреждающего просмотра — в данном случае отрицательного упреждающего просмотра. Документы Kate/QRegExp утверждают, что просмотр вперед поддерживается, но группы без захвата - например. (?:...) -- нет, поэтому в этом последнем регулярном выражении использовались все группы захвата.

Если у вас есть возможность переключиться на другой редактор, я настоятельно рекомендую вам это сделать. Мне больше всего нравится EditPad Pro; у него лучшая поддержка регулярных выражений, которую я когда-либо видел в редакторе.

person Alan Moore    schedule 09.09.2012