Przykład z wyrażeniem regularnym: analizator składni Wiki

Flash Player 9 i nowsze wersje, Adobe AIR 1.0 i nowsze wersje

Ten prosty przykład konwersji tekstu Wiki ilustruje wiele zastosowań dla wyrażeń regularnych:

  • Konwertowanie wierszy tekstu dopasowanych do źródłowego wzorca Wiki na odpowiednie wyjściowe ciągi znaków HTML.

  • Użycie wyrażenia regularnego w celu konwersji wzorców adresów URL na znaczniki hiperłączy HTML <a> .

  • Użycie wyrażenia regularnego w celu konwersji ciągów znaków amerykańskiego dolara (np. "$9.95" ) na ciągi znaków euro (np. "8.24 €" ).

Aby pobrać pliki tej przykładowej aplikacji, należy przejść na stronę www.adobe.com/go/learn_programmingAS3samples_flash_pl . Pliki aplikacji WikiEditor można znaleźć w folderze Samples/WikiEditor. Aplikacja składa się z następujących plików:

File

Opis

WikiEditor.mxml

lub

WikiEditor.fla

Główny plik aplikacji w formacie Flash (FLA) lub Flex (MXML).

com/example/programmingas3/regExpExamples/WikiParser.as

Klasa zawierająca metody, które używają wyrażeń regularnych w celu konwersji wejściowych wzorców tekstu Wiki na odpowiednie dane wyjściowe HTML.

com/example/programmingas3/regExpExamples/URLParser.as

Klasa zawierająca metody, które używają wyrażeń regularnych w celu konwersji ciągów znaków adresu URL na znaczniki hiperłącza HTML <a> .

com/example/programmingas3/regExpExamples/CurrencyConverter.as

Klasa zawierająca metody, które używają wyrażeń regularnych w celu konwersji ciągów znaków dolara amerykańskiego na ciągów znaków euro.

Definiowanie klasy WikiParser

Klasa WikiParser zawiera metody, które konwertują wejściowy tekst Wiki na odpowiednie wyjściowe dane HTML. Nie jest to zbyt stabilna aplikacja konwersji Wiki, ale ilustruje kilka dobrych zastosowań wyrażeń regularnych do dopasowywania wzorców i konwersji ciągów znaków.

Funkcja konstruktora razem z metodą setWikiData() inicjuje przykładowy ciąg znaków wejściowego tekstu Wiki, co ilustruje poniższy przykład:

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

Gdy użytkownik kliknie przycisk Test w przykładowej aplikacji, aplikacja wywołuje metodę parseWikiString() obiektu WikiParser. Metoda wywołuje kilka innych metod, które w odpowiedzi gromadzą wynikowy ciąg znaków HTML.

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

Każda z wywołanych metod — parseBold() , parseItalic() , linesToParagraphs() i parseBullets() — używa metody replace() ciągu znaków w celu zasępienia dopasowanych wzorców, zdefiniowanych przez wyrażenie regularne, aby dokonać transformacji wejściowego tekstu Wiki na tekst w formacie HTML.

Konwertowanie wzorców pogrubionych i kursywy

Metoda parseBold() wyszukuje pogrubiony wzorzec tekstu Wiki (np. '''foo''' ) i przekształca go na jego odpowiedni tekst w formacie HTML (np. <b>foo</b> ), co ilustruje poniższy przykład:

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

Należy zauważyć, że fragment (.?*) wyrażenia regularnego dopasowuje dowolną ilość znaków ( * ) między dwoma definiującymi wzorcami ''' . Kwantyfikator ? zmienia dopasowanie na nongreedy, dlatego dla przykładowego ciągu znaków '''aaa''' bbb '''ccc''' , pierwszym dopasowanym ciągiem będzie '''aaa''' , a nie cały ciąg (który rozpoczyna się i kończy wzorcem ''' ).

Nawiasy okrągłe w wyrażeniu regularnym definiują grupę przechwyconą, a metoda replace() odwołuje się do tej grupy za pomocą kodu $1 w ciągu zastępowania. Flaga g ( global ) w wyrażeniu regularnym zapewnia, że metoda replace() zastąpi wszystkie dopasowania w ciągu znaków (nie tylko pierwsze).

Metoda parseItalic() działa podobnie do metody parseBold() poza tym, że sprawdza dwa apostrofy ( '' ) tak, jak separator dla kursywy (nie trzy):

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

Konwertowanie wzorców punktów

Tak jak ilustruje poniższy przykład metoda parseBullet() wyszukuje wzorca wiersza punktu Wiki (np. * foo ) i przekształca go na odpowiedni tekst w formacie HTML (np. <li>foo</li> ):

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

Symbol ^ na początku wyrażenia regularnego dopasowuje początek wiersza. Flaga m ( multiline ) w wyrażeniu regularnym powoduje, że wyrażenie regularne dopasuje symbol ^ do początku wiersza, a nie do początku ciągu znaków.

Wzorzec \* dopasowuje znak gwiazdki (odwrócony ukośnik używany jest do sygnalizowania literalnej gwiazdki zamiast kwantyfikatora * ).

Nawiasy okrągłe w wyrażeniu regularnym definiują grupę przechwyconą, a metoda replace() odwołuje się do tej grupy za pomocą kodu $1 w ciągu zastępowania. Flaga g ( global ) w wyrażeniu regularnym zapewnia, że metoda replace() zastąpi wszystkie dopasowania w ciągu znaków (nie tylko pierwszy).

Konwertowanie wzorców akapitów Wiki

Metoda linesToParagraphs() konwertuje każdy wiersz w wejściowym ciągu znaków Wiki na znacznik akapitu HTML <p> . Te wiersze metody usuwają puste wiersze z wejściowego ciągu znaków Wiki:

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

Symbole ^ i $ wyrażenia regularnego dopasowują początek i koniec wiersza. Flaga m ( multiline ) w wyrażeniu regularnym powoduje, że wyrażenie regularne dopasuje symbol ^ do początku wiersza, a nie do początku ciągu znaków.

Metoda replace() zastępuje wszystkie dopasowane podciągi (puste wiersze) pustym ciągiem znaków ( "" ). Flaga g ( global ) w wyrażeniu regularnym zapewnia, że metoda replace() zastąpi wszystkie dopasowania w ciągu znaków (nie tylko pierwsze).

Konwertowanie adresów URL na znaczniki HTML <a>

Gdy użytkownik kliknie przycisk Test w przykładowej aplikacji i zaznaczone jest pole wyboru urlToATag , wywołana zostanie statyczna metoda URLParser.urlToATag() w celu konwersji ciągów znaków URL z wejściowych ciągów Wiki na znaczniki HTML <a> .

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>");

Funkcja konstruktora RegExp() używana jest do tworzenia wyrażenia regularnego ( urlPattern ) z wielu części składowych. Części składowe są ciągami znaków, które definiują fragment wzorca wyrażenia regularnego.

Pierwsza część wzorca wyrażenia regularnego, zdefiniowaną w ciągu znaków protocol , definiuje protokół URL: http:// lub ftp:// . Nawiasy okrągłe definiują grupę nieprzechwyconą wskazywaną przez symbol ? . Oznacza to, że nawiasy okrągłe używane są do definiowania grupy dla wzorca alternatywy | ; grupa nie dopasuje kodów odwołania wstecznego ( $1 , $2 , $3 ) w ciągu zastępowania metody replace() .

Wszystkie pozostałe części składowe wyrażenia regularnego używają grup przechwyconych (wskazywanych przez nawiasy okrągłe we wzorcu), które używane są następnie w kodach odwołania wstecznego ( $1 , $2 , $3 ) w ciągu zastępowania metody replace() .

Część wzorca definiowana przez ciąg znaków urlPart dopasowuje co najmniej jeden z następujących znaków: a-z , 0-9 , _ lub - . Kwantyfikator + wskazuje, że dopasowany jest co najmniej jeden znak. \. wskazuje wymagany znak kropki ( . ). Reszta dopasowuje inny ciąg znaków do co najmniej jednego z następujących znaków: a-z , 0-9 , _ lub - .

Część wzorca zdefiniowana przez ciąg znaków optionalUrlPart dopasowuje zero lub więcej z następujących znaków: kropka ( . ), po której następuje dowolna liczba znaków alfanumerycznych (łącznie z _ i - ). Kwantyfikator * wskazuje, że dopasowanych jest zero lub więcej znaków.

Wywołanie metody replace() powoduje zastosowanie wyrażenia regularnego i złożenie ciągu znaków zastępowania HTML za pomocą odwołania wstecznego.

Następnie metoda urlToATag() wywołuje metodę emailToATag() , która używa podobnych technik w celu zastąpienia wzorców e-mail ciągami znaków hiperłącza HTML <a> . Wyrażenia regularne użyte do dopasowania protokołów HTTP, FTP i adresów URL e-mail w przykładowym pliku są dość proste i użyte zostały w celu zilustrowania przykładu; istnieją dużo bardziej złożone wyrażenia regularne do dokładniejszego dopasowywania adresów URL.

Konwertowanie ciągów znaków dolara amerykańskiego na ciągi znaków euro

Gdy użytkownik kliknie przycisk Test w przykładowej aplikacji i zaznaczone jest pole wyboru dollarToEuro , wywołana zostanie statyczna metoda CurrencyConverter.usdToEuro() w celu konwersji ciągów znaków dolara amerykańskiego (np. "$9.95" ) na ciągi znaków euro (np. "8.24 €" ), co ilustruje poniższy przykład:

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

Pierwszy wiersz definiuje prosty wzorzec do dopasowania ciągów znaków dolara amerykańskiego. Należy zauważyć, że znak $ poprzedzony jest znakiem zmiany znaczenia — odwróconym ukośnikiem ( \ ).

Metoda replace() używa wyrażenia regularnego jako modułu dopasowania wzorca i wywołuje funkcję usdStrToEuroStr() , aby określić ciąg znaków zastępowania (wartość w euro).

Gdy jako drugi argument w wywołaniu metody replace() zostanie użyta nazwa funkcji, jako parametry do wywołanej funkcji przekazywane zostaną:

  • Zgodny fragment ciągu.

  • Wszystkie przechwycone dopasowania grupy ujęte w nawias Liczba argumentów przekazanych w ten sposób różni się w zależności od liczby przechwyconych dopasowania grupy ujęte w nawias. Liczbę przechwyconych dopasowań grupy ujęte w nawias można określić przez sprawdzenie arguments.length - 3 w kodzie funkcji.

  • Położenie indeksu w miejscu rozpoczęcia dopasowania w ciągu znaków.

  • Kompletny ciąg znaków.

Metoda usdStrToEuroStr() konwertuje wzorzec ciągu znaków na ciągi znaków euro, co ilustruje poniższy przykład:

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;  
}

Należy zauważyć, że args[1] reprezentuje przechwyconą grupę ujętą w nawiasy dopasowaną przez wyrażenie regularne usdPrice . Jest to fragment numeryczny ciągu znaków dolara amerykańskiego: tzn. kwota bez znaku $ . Metoda stosuje konwersję kursu walutowego i zwraca wynikowy ciąg znaków (umieszczając na końcu symbol € zamiast początkowego symbolu $).