2010-05-21 16 views
19

W JavaScript:UTF-8 słowo granica regex w javascript

"ab abc cab ab ab".replace(/\bab\b/g, "AB"); 

poprawnie daje mi:

"AB abc cab AB AB" 

Kiedy używać UTF-8 znaków choć:

"αβ αβγ γαβ αβ αβ".replace(/\bαβ\b/g, "AB"); 

word boundary operator nie działa:

"αβ αβγ γαβ αβ αβ" 

Czy istnieje rozwiązanie tego problemu?

+1

JavaScript nie używa 'UTF-8' dla Unicode. Zgodnie ze standardem implementacja może wykorzystywać "UCS-2" lub "UTF-16", jak sądzę. Oznacza to, że operujesz na tekście, który został przekonwertowany na jeden z tych formatów lub możesz pracować na tekście, w którym każdy "oktet" (bajt) każdego z punktów kodowych Unicode został przekonwertowany na jeden z tych formatów, w zależności od tego, jak kod pobiera tekst. – hippietrail

Odpowiedz

22

Słowo granica twierdzenie pasuje tylko jeśli postać słowo nie występuje przed lub przez inną postać słowa (tak .\b. jest równa \W\w i \w\W). I \w jest zdefiniowany jako [A-Za-z0-9_]. Tak więc \w nie pasuje do greckich znaków. W związku z tym nie można używać do tego przypadku numeru \b.

Co można zrobić zamiast tego jest użycie:

"αβ αβγ γαβ αβ αβ".replace(/(^|\s)αβ(?=\s|$)/g, "$1AB") 
+0

dzięki. Przydatne jest również użycie notacji z wyprzedzeniem (? = ...). Czy można to zrobić bez niego? – cherouvim

+3

@cherouvim: Nie, zajmowałoby to miejsce po słowie, które jest początkiem następnego wyszukiwania.Po prostu patrząc na '" αβ αβ "', pierwszy mecz pochłonie '" αβ | αβ "' ('|' wskazuje wewnętrzny wskaźnik), a ostatnia część nie zostanie dopasowana, ponieważ nie ma już miejsca wiodącego. Ale ponieważ asercja nie pochłania znaków, pozycją wskaźnika po pierwszym dopasowaniu będzie "" αβ | αβ "', a wiodąca przestrzeń zostanie zachowana dla następnego dopasowania. – Gumbo

+1

To nie jest tak samo jak granica słowa. Na przykład nie pasuje do 'αβ!'. –

1

Nie wszystkie implementacje RegEx związane z silnikami Javascript Unicode świadomych.

Na przykład Microsoft JScript w IE jest ograniczony do ANSI.

2

Nie wszystkie realizacja regexp Javascript posiada wsparcie dla Unicode reklamy więc trzeba uciec

"αβ αβγ γαβ αβ αβ".replace(/\u03b1\u03b2/g, "AB"); // "AB ABγ γAB AB AB" 

odwzorowywania znaków można przyjrzeć http://htmlhelp.com/reference/html40/entities/symbols.html

oczywiście, to nie pomaga z zagadnieniem granicy wyrazów (jak wyjaśniono w innych odpowiedziach), ale powinno przynajmniej umożliwić odpowiednie dopasowanie znaków.

+0

Dlaczego więc nie użyjesz tych samych znaków ucieczki Unicode również do napisu? – Gumbo

+0

Ponieważ jeden jest przetwarzany jako ciąg, a drugi jako literalne wyrażenie regularne - nie jestem pewien, czy to ma znaczenie .. –

+3

Ale jeśli implementacja wyrażenia regularnego nie obsługuje Unicodu, w jaki sposób jest sekwencją unikodową Unicode, jak '\ u03b1' powinien być interpretowany? – Gumbo

1

Kiedy masz do czynienia ze słowami Unicode i słowami naturalnymi, prawdopodobnie chcesz być bardziej ostrożny. z granicami niż tylko używanie \b. Aby uzyskać szczegółowe informacje i wskazówki dojazdu, patrz this answer.

2

potrzebowałem czegoś by być programowany i obsługiwać znaki interpunkcyjne, wsporniki itp

http://jsfiddle.net/AQvyd/

var wordToReplace = '買い手', 
    replacementWord = '[[BUYER]]', 
    text = 'Mange 買い手 information. The selected Store and Classification will be the default on the สั่งซื้อ.' 

function replaceWord(text, wordToReplace, replacementWord) { 
    var re = new RegExp('(^|\\s|\\(|\'|"|,|;)' + wordToReplace + '($|\\s|\\)|\\.|\'|"|!|,|;|\\?)', 'gi'); 
    return text.replace(re, replacementWord); 
} 

Pisałem edytora zasobów javascript tak dlatego znalazłem tę stronę, a także odpowiedział na to z konieczności, ponieważ nie mogłem znaleźć słowa sparametryzowanego sparametryzowanego wiersza, które działało dobrze dla Unicode.

+0

Właściwie powinienem uciekać z "wordToReplace" z "\" w zarezerwowanych znakach. Będę musiał to zaktualizować. –