Javascript RegExp + les limites de Mot + caractères unicode
Je suis à la recherche du bâtiment, et je vais utiliser le javascript de saisie semi-automatique avec elle. Je suis originaire de Finlande (finnois) donc je dois gérer avec certains caractères spéciaux comme ä, ö et å
Lorsque l'utilisateur tape du texte dans le champ de saisie de recherche j'ai essayer de faire correspondre le texte de données.
Ici est simple exemple qui ne fonctionne pas correctement si l'utilisateur tape par exemple """ingénierie". Même chose avec "äl"
var title = "this is simple string with finnish word tämä on ääkköstesti älkää ihmetelkö";
//Does not work
var searchterm = "äl";
//does not work
//var searchterm = "ää";
//Works
//var searchterm = "wi";
if ( new RegExp("\\b"+searchterm, "gi").test(title) ) {
$("#result").html("Match: ("+searchterm+"): "+title);
} else {
$("#result").html("nothing found with term: "+searchterm);
}
Alors, comment puis-je obtenir ces ä,ö et å caractères de travailler avec javascript regex?
Je pense que je dois utiliser les codes unicode, mais comment dois-je faire? Codes pour ces caractères sont les suivants:
[\u00C4,\u00E4,\u00C5,\u00E5,\u00D6,\u00F6]
=> äÄåÅöÖ
- C'est quoi "\\b" ?
\b
signifie "mot" dans une expression régulière; la barre oblique est échappé ici parce que c'est dans une chaîne de caractères.- Merci, bizarre que je n'avais pas vu qu'avant :/
- J'utilise le \b parce que je veux correspondre au début de chaque mot.
- Comme vous le voyez, le Javascript est coincé dans l'idiot des années 1960 de style ASCII uniquement mentalité. Il ne répond pas, même les plus élémentaires exigences de conformité nécessaires pour le Niveau 1 de Base de Support de l'Unicode” par UT#18 sur Unicode Expressions Régulières. En essayant de faire du vrai texte Unicode-travaux de traitement en Javascript une affreuse blague, et une cruelle, trop: il ne peut pas être fait. Le XRegexp plugin mentionné ci-dessous est nécessaire, mais pas suffisante, pour ces fins.
- Les nouveaux arrivants attention: Cela ne peut être fait dans la regexp. Pas avec
\b
, pas avec\s
, pas avec XRegExp, pas avec lookaheads ou lookarounds. Croyez-moi, j'ai tout essayé, et tout cassé dans l'une ou l'autre manière. Le seul moyen que j'ai trouvé que jusqu'à maintenant les œuvres est l'encodage de la chaîne unicode retour à l'ascii et effectuer un ascii regexp rechercher/remplacer avec\b
comme prévu à l'origine. Voir ici: stackoverflow.com/a/10590188/1329367
Vous devez vous connecter pour publier un commentaire.
Il semble y avoir un problème avec la Regex et la limite de mot
\b
correspondant au début d'une chaîne de caractères avec un caractère de départ hors de la normale 256 octets gamme.Au lieu d'utiliser
\b
, essayez d'utiliser(?:^|\\s)
Ventilation:
(?:
parenthèse()
former un groupe de capture dans la Regex. Parenthèse a commencé avec un point d'interrogation et du côlon?:
forme d'un non-capture d'un groupe. Ils ont juste le groupe de l'ensemble des termes^
l'accent circonflexe correspond au début d'une chaîne de|
le bar est l'opérateur "ou".\s
correspond aux espaces (apparaît comme\\s
de la chaîne car nous avons pour échapper à la barre oblique inverse))
ferme le groupeDonc, au lieu d'utiliser
\b
, ce qui correspond à des frontières de mot et ne fonctionne pas pour les caractères unicode, nous utilisons un non-capture d'un groupe qui correspond au début d'une chaîne de caractères OU espaces.(?:^|\\s)
vraiment faire? Vous n'avez pas expliquer cette solution à tout.(?:^|\\s)
n'est pas un zéro-largeur affirmation comme\b
est, et consomment de caractères à partir de la correspondance. Une anticipation positif serait une meilleure idée ((?=^|\\s)
) mais ne les travaux après le match, comme lookbehind est toujours pas pris en charge. Aussi, les limites de word ne sont pas seulement des espaces et de la chaîne des frontières, mais une tonne d'autres personnages.'¿dónde está la alcaldesa?'
:es
etestá
sont appariés, ce qui est mauvais. Seulementestá
doit être adapté.\\b
est censé être utile avec les limites des mots.La
\b
classe de caractères en JavaScript RegEx est vraiment utile avec un simple codage ASCII.\b
est un raccourci du code de la limite entre\w
et\W
ensembles ou\w
et le début ou la fin de la chaîne. Ces jeux de caractères ne prendre en compte ASCII de "mot" de personnages, où\w
est égal à[a-zA-Z0-9_]
et\W
est la négation de cette classe.Ce qui rend la RegEx classes de caractère en grande partie inutile pour traiter avec une vraie langue.
\s
doit travailler pour ce que vous voulez faire, à condition que les termes de recherche ne sont délimités par des espaces.\b
n'est pas une classe de caractères sténographiques comme\w
et\s
, c'est un zéro-largeur affirmation comme\A
,$
, et lookarounds.cette question est vieux, mais je crois que j'ai trouvé une meilleure solution pour le contour dans les expressions régulières avec unicode lettres.
À l'aide de XRegExp vous pouvez mettre en œuvre un valide \b limite l'expansion de cette
le résultat est un 4000+ char de long, mais il semble fonctionner assez performants.
Quelques explications: (?= ) est un zéro-longueur d'anticipation qui ressemble à un début ou de fin de frontière ou d'une lettre de caractères unicode. Le plus important je pense est le lookahead, parce que le \b ne capture rien: c'est tout simplement vrai ou faux.
Je vous recommande d'utiliser XRegExp lorsque vous devez travailler avec un ensemble spécifique de caractères Unicode, l'auteur de cette bibliothèque cartographié l'ensemble régional des ensembles de caractères rend le travail avec les différentes langues plus facile.
J'ai remarqué quelque chose de vraiment bizarre avec
\b
lors de l'utilisation de l'Unicode:Il semble que le sens de
\b
et\B
sont inversés, mais seulement lorsqu'il est utilisé avec des non-ASCII Unicode? Il y a peut être quelque chose de plus profond qui se passe ici, mais je ne suis pas sûr de ce qu'il est.En tout cas, il semble que le mot frontière est le problème, pas l'Unicode des caractères eux-mêmes. Peut-être vous devriez juste remplacer
\b
avec(^|[\s\\/-_&])
, comme cela semble fonctionner correctement. (Faites votre liste de symboles plus complète que la mienne, si.)\b
et\B
ne sont pas Unicode-connaissance en JavaScript, donc ils considèrentä
un caractère non-alphanumérique et donc voir une limite de mot entrep
etä
.Mon idée est de rechercher avec les codes représentant les lettres finlandaises
new RegExp("\\b"+asciiOnly(searchterm), "gi").test(asciiOnly(title))
Mon idée de départ était d'utiliser de la plaine
encodeURI
mais le signe % semble interférer avec la regexp.http://jsfiddle.net/7TsxB/5/
J'ai écrit un brut de la fonction en utilisant encodeURI pour coder chaque caractère de code 128, mais le retrait de ses % et en ajoutant 'QQ' au début. Il n'est pas le meilleur marqueur mais je ne pouvais pas non alphanumérique de travail.
QQ
vous pouvez utiliser un contrôle de la chaîne de___
qui est un peu plus sûr et toujours en ascii, et au lieu deencodeURI
vous pouvez tirer parti du javascript natifescape
/unescape
méthodes, mais sinon, il fait le travail.J'ai eu un problème similaire, mais j'ai dû remplacer un éventail de conditions. Toutes les solutions que j'ai trouvé n'a pas travaillé, si deux termes sont dans le texte à côté de l'autre (en raison de leurs limites overlaped). J'ai donc dû utiliser un peu modifié:
Voir le code dans un violon: http://jsfiddle.net/antoninslejska/bvbLpdos/1/
L'expression régulière est inspiré par: http://breakthebit.org/post/3446894238/word-boundaries-in-javascripts-regular
Je ne peux pas dire que je trouve la solution élégante...
Ce que vous cherchez est de l'Unicode des limites de mots standard:
http://unicode.org/reports/tr29/tr29-9.html#Word_Boundaries
Il y a un JavaScript de mise en œuvre ici (unciodejs.wordbreak.js)
https://github.com/wikimedia/unicodejs