2015-11-07 10 views
6

Warum ist das false:Unicode und: alpha:

iex(1)> String.match?("汉语漢語", ~r/^[[:alpha:]]+$/) 
false 

Aber das ist true:

iex(2)> String.match?("汉语漢語", ~r/[[:alpha:]]/) 
true 

Manchmal [:alpha:] ist Unicode und manchmal ist es nicht?

EDIT:

Ich glaube nicht mein ursprüngliches Beispiel klar genug war.

Warum ist das false:

iex(1)> String.match?("汉", ~r/^[[:alpha:]]+$/) 
false 

Aber das ist true:

iex(2)> String.match?("汉", ~r/[[:alpha:]]/) 
true 
+0

Versuchen Sie es mit dem Modifizierer '/ u':' ~ r/^ [[: alpha:]] + $/u'. –

+0

Danke. Ich verstehe den Modifikator "u". Ich hätte auch '\ p {L}' machen können. Meine Frage ist, warum funktioniert '[: alpha:]' in diesen beiden Beispielen anders? – mwoods79

+3

Wenn Sie die Zeichenfolge im Nicht-Unicode-Modus an die Regex übergeben, wird sie als Array von Bytes und nicht als Unicode-Zeichenfolge behandelt. Siehe 'IO.puts byte_size (" 汉语 漢語 ")' und 'IO.puts String.length (" 汉语 漢語 ")' Unterschied. Es gibt Bytes in der Zeichenfolge, die nicht mit der POSIX-Zeichenklasse "[: alpha:]" abgeglichen werden können. Daher funktioniert der erste Ausdruck nicht, während der zweite Ausdruck nur 1 Zeichen benötigt, um eine gültige Übereinstimmung zurückzugeben. –

Antwort

11

Wenn Sie die Zeichenfolge an die Regex in einem Nicht-Unicode-Modus passieren, es als Array behandelt wird von Bytes, nicht als Unicode-String. Siehe IO.puts byte_size("汉语漢語") (12, alle Bytes, aus denen der Eingang besteht: 230,177,137,232,175,173,230,188,162,232,170,158) und IO.puts String.length("汉语漢語") (4, die Unicode "Buchstaben") Unterschied. In der Zeichenfolge befinden sich Bytes, die nicht mit der POSIX-Zeichenklasse [:alpha:] übereinstimmen. Daher funktioniert der erste Ausdruck nicht, während der zweite funktioniert, da er nur 1 Zeichen benötigt, um eine gültige Übereinstimmung zurückzugeben.

Um richtig Unicode-Strings mit PCRE regex Bibliothek übereinstimmen (das in Elixir verwendet wird), müssen Sie den Unicode-Modus mit /u Modifikator aktivieren:

IO.puts String.match?("汉语漢語", ~r/^[[:alpha:]]+$/u) 

anzeigen IDEONE demo (prints true)

siehe Elixir regex reference:

unicode (u) - Unicode-spezifische Muster wieermöglichtund ändert Modifikatoren wie \w, \W, \s und Freunde auch auf Unicode übereinstimmen. Es erwartet gültige Unicode-Zeichenfolgen bei der Übereinstimmung.