Пример регулярных выражений: синтаксический анализатор Wiki

Flash Player 9 и более поздних версий, Adobe AIR 1.0 и более поздних версий

Простой пример преобразования текста Wiki показывает ряд случаев применения регулярных выражений.

  • Преобразование строк текста, при котором происходит совпадение исходного образца Wiki с определенными выводными строками HTML.

  • Использование регулярного выражения с целью преобразования образцов URL в теги гиперссылок <a> HTML.

  • Использование регулярного выражения с целью преобразования строк символа доллара США (таких как "$9.95") в строки символа евро (такие как "8.24 €").

Получить файлы приложения для этого примера можно на странице www.adobe.com/go/learn_programmingAS3samples_flash_ru. Файлы с образцами применения WikiEditor можно найти в папке Samples/WikiEditor. Приложение состоит из следующих файлов.

File

Описание

WikiEditor.mxml

или

WikiEditor.fla

Основной файл приложения Flash (FLA) или Flex (MXML).

com/example/programmingas3/regExpExamples/WikiParser.as

Класс, включающий методы, которые используют регулярные выражения для преобразования образцов вводимого текста Wiki в эквивалентный выводной текст HTML.

com/example/programmingas3/regExpExamples/URLParser.as

Класс, включающий методы, которые используют регулярные выражения для преобразования строк URL в теги гиперссылок <a> HTML.

com/example/programmingas3/regExpExamples/CurrencyConverter.as

Класс, включающий методы, которые используют регулярные выражения для преобразования строк символа доллара США в строки евро.

Определение класса WikiParser

Класс WikiParser включает методы, которые преобразуют вводимый текст Wiki в эквивалентный выводной текст HTML. Этот случай применения преобразования не является достаточно устойчивым к сбоям, но, тем не менее, он иллюстрирует некоторые хорошие примеры использования регулярных выражений для совпадения образцов и преобразования строк.

Функция конструктора вместе с методом setWikiData() просто инициализирует строку примера вводимого текста Wiki следующим образом:

public function WikiParser() 
{ 
    wikiData = setWikiData(); 
}

Когда пользователь нажимает в демонстрационном приложении кнопку «Проверка», приложение запускает метод parseWikiString() объекта WikiParser. Этот метод вызывает ряд других методов, которые, в свою очередь, компонуют получившиеся на выводе строки HTML.

public function parseWikiString(wikiString:String):String 
{ 
    var result:String = parseBold(wikiString); 
    result = parseItalic(result); 
    result = linesToParagraphs(result); 
    result = parseBullets(result); 
    return result; 
}

Каждый из этих вызванных методов — parseBold(), parseItalic(), linesToParagraphs() и parseBullets() — использует метод replace() строки с целью замещения совпадающих образцов, определенных регулярным выражением, чтобы преобразовать вводимый текст Wiki в текст формата HTML.

Преобразование образцов полужирного и курсивного шрифтов

Метод parseBold() производит поиск образца полужирного шрифта Wiki (к примеру, '''foo''') и преобразует его в эквивалентный текст HTML (к примеру, <b>foo</b>) следующим образом:

private function parseBold(input:String):String 
{ 
    var pattern:RegExp = /'''(.*?)'''/g; 
    return input.replace(pattern, "<b>$1</b>"); 
}

Следует отметить, что часть (.?*) регулярного выражения соответствует любому числу символов (*) между двумя определяющими образцами '''. Квантификатор ? делает совпадение непоглощающим с тем, чтобы для строки, такой как '''aaa''' bbb '''ccc''', первой совпадающей строкой была '''aaa''', а не вся строка (находящаяся внутри образца ''').

Круглые скобки в регулярном выражении определяют группу сбора, а метод replace() ссылается на эту группу с помощью кода $1 в замещающей строке. Флаг g (global) в регулярном выражении обеспечивает замещение методом replace() всех совпадений в строке (а не только первого совпадения).

Метод parseItalic() функционирует практически так же, как и метод parseBold(), за исключением того, что он проверяет наличие двух (не трех) апострофов (''), выполняющих роль ограничителей курсивного текста:

private function parseItalic(input:String):String 
{ 
    var pattern:RegExp = /''(.*?)''/g; 
    return input.replace(pattern, "<i>$1</i>"); 
}

Преобразование образцов маркера абзаца

Как показывает следующий пример, метод parseBullet() производит поиск образца строки маркера абзаца Wiki, (к примеру, * foo) и преобразует его в эквивалентный текст HTML (к примеру, <li>foo</li>):

private function parseBullets(input:String):String 
{ 
    var pattern:RegExp = /^\*(.*)/gm; 
    return input.replace(pattern, "<li>$1</li>"); 
}

Символ ^ в начале регулярного выражения соответствует началу строки. Флаг m (multiline) в регулярном выражении является причиной того, что регулярное выражение сопоставляет символ ^ началу линии, а не просто началу строки.

Образец \* соответствует символу звездочки (обратная косая черта используется для обозначения звездочки литерала вместо квантификатора *).

Круглые скобки в регулярном выражении определяют группу сбора, а метод replace() ссылается на эту группу с помощью кода $1 в замещающей строке. Флаг g (global) в регулярном выражении обеспечивает замещение методом replace() всех совпадений в строке (а не только первого совпадения).

Преобразование образцов Wiki абзаца

Метод linesToParagraphs() преобразует каждую линию во входной строке Wiki в тег абзаца <p> HTML. Линии этого метода убирают пустые линии из входной строки Wiki:

var pattern:RegExp = /^$/gm; 
var result:String = input.replace(pattern, "");

Символы ^ и $ соответствуют началу и концу строки регулярного выражения. Флаг (multiline) m в регулярном выражении является причиной того, что регулярное выражение сопоставляет символ ^ началу линии, а не просто началу строки.

Метод replace() замещает все совпадающие подстроки (пустые линии) пустой строкой (""). Флаг g (global) в регулярном выражении обеспечивает замещение методом replace() всех совпадений в строке (а не только первого совпадения).

Преобразование URL-адресов в теги <a> HTML

При нажатии в демонстрационном приложении кнопки «Проверка» и установке флажка urlToATag приложение вызывает статический метод URLParser.urlToATag() для преобразования строк URL из входной строки Wiki в теги <a> HTML.

var protocol:String = "((?:http|ftp)://)"; 
var urlPart:String = "([a-z0-9_-]+\.[a-z0-9_-]+)"; 
var optionalUrlPart:String = "(\.[a-z0-9_-]*)"; 
var urlPattern:RegExp = new RegExp(protocol + urlPart + optionalUrlPart, "ig"); 
var result:String = input.replace(urlPattern, "<a href='$1$2$3'><u>$1$2$3</u></a>");

Конструктор RegExp() используется для сборки нескольких составных частей в единое регулярное выражение (urlPattern). Этими составными частями являются отдельные строки, образующие часть образца регулярного выражения.

Первая часть образца регулярного выражения, определяемая строкой protocol, определяет URL-протокол: либо http:// , либо ftp://. Круглые скобки определяют группу без сбора, обозначенную символом ?. Это означает, что круглые скобки используются лишь для того, чтобы определять группу для образца перестановки |; эта группа не будет соответствовать кодам обратных ссылок ($1, $2, $3) в замещающей строке метода replace().

Другие составные части регулярного выражения используют группы сбора (обозначенные в образце круглыми скобками), которые впоследствии используются в кодах обратных ссылок ($1, $2, $3) в замещающей строке метода replace().

Часть образца, определяемая строкой urlPart, соответствует, по крайней мере, одному из следующих символов: a-z, 0-9, _ или -. Квантификатор + указывает на совпадение по крайней мере одного символа. \. обозначает символ (.) обязательной точки. И оставшаяся часть образца соответствует другой строке с по крайней мере одним из следующих символов: a-z, 0-9, _ или -.

Часть образца, определяемая строкой optionalUrlPart, соответствует нуль или более раз следующему: символу точки (.), за которым идет ряд буквенно-цифровых символов (в том числе _ и -). Квантификатор * указывает на совпадение нуля или более символов.

При вызове метода replace() используется регулярное выражение, а с помощью обратных ссылок осуществляется сборка замещающих строк HTML.

Метод urlToATag() затем вызывает метод emailToATag(), который для замещения образцов электронной почты строками гиперссылок <a> HTML использует схожие механизмы. Регулярные выражения, используемые в этом демонстрационном файле для подбора HTTP, FTP, URL-адресов электронной почты, достаточно просты для приведения в качестве примера; существуют гораздо более сложные регулярные выражения для более правильного сопоставления таких URL-адресов.

Преобразование строк символа доллара США в строки символа евро

При нажатии в демонстрационном приложении кнопки «Проверка» и установке флажка dollarToEuro приложение вызывает статический метод CurrencyConverter.usdToEuro() для преобразования строк символа доллара США (например, "$9.95") в строки символа евро (например, "8.24 €") следующим образом:

var usdPrice:RegExp = /\$([\d,]+.\d+)+/g; 
return input.replace(usdPrice, usdStrToEuroStr); 

Первая линия определяет простой образец для подбора строк символа доллара США. Обратите внимание, что символу $ предшествует символ перехода \ обратной косой черты.

Метод replace() использует регулярное выражение в качестве обнаружителя совпадений образцов, а также вызывает функцию usdStrToEuroStr() для определения замещающей строки (значения в евро).

Когда имя функции используется в качестве второго параметра метода replace(), следующие элементы передаются в вызванную функцию в качестве параметров.

  • Совпадающая часть строки.

  • Любые собранные совпадения групп в круглых скобках. Количество переданных таким образом аргументов варьируется в зависимости от количества собранных совпадений групп в круглых скобках. Количество собранных совпадений групп в круглых скобках можно определить, проверив значение параметра arguments.length - 3 в коде функции.

  • Позиция в индексе в строке, где начинается совпадение.

  • Строка полностью.

Метод usdStrToEuroStr() преобразует образцы строк символа доллара США в строки символа евро следующим образом:

private function usdToEuro(...args):String 
{ 
    var usd:String = args[1]; 
    usd = usd.replace(",", ""); 
    var exchangeRate:Number = 0.828017; 
    var euro:Number = Number(usd) * exchangeRate; 
    trace(usd, Number(usd), euro); 
    const euroSymbol:String = String.fromCharCode(8364); // € 
    return euro.toFixed(2) + " " + euroSymbol;  
}

Обратите внимание, что args[1] представляет собранную группу в круглых скобках, подобранную регулярным выражением usdPrice. Это числовая часть строки символа доллара США: сумма долларов без знака $. Данный метод использует преобразование курсов валют и возвращает итоговую строку (с замыкающим символом € вместо ведущего символа $).