Reproduire l'expression canonique Python r '\ w (? U)' en JavaScript

La compatibilité des expressions régulières entre les langues est un problème difficile. Il y a longtemps, lorsque j'ai implémenté l'interpréteur Ruby sur Python, je faisais référence à l'analyseur Ruby de Ruby, mais je ne pouvais pas le porter correctement et ne pouvais pas créer un analyseur complet. Bon, c'est bien.

J'ai eu un rapport de bogue sur Sphinx et j'ai rencontré à nouveau un problème de compatibilité des expressions régulières, mais je vais en laisser une note car certaines personnes dans d'autres langues peuvent avoir des problèmes avec le problème.

Circonstances du Sphinx

Sphinx est un générateur de documents qui génère du HTML statique. Vous pouvez générer des PDF via Latex et diverses sorties telles que texinfo et man. Le HTML est probablement le plus utilisé. Le point caractéristique de la sortie HTML est de créer un index de recherche en Python et de le rendre JSON. Le navigateur lit le JSON et effectue des recherches.

En Python, les termes de recherche sont créés en divisant les phrases en mots selon certaines règles. Même en JavaScript, après avoir divisé les termes de recherche en mots, la recherche est effectuée à l'aide du dictionnaire créé côté Python.

JavaScript faisait le fractionnement de mots avec l'expression régulière suivante

/\s+/

Python a utilisé les expressions régulières suivantes comme mots à associer.

re.compile(r'\w+(?u)')

Dans les deux cas, les délimiteurs d'espace autorisent les délimiteurs de mots, il n'y a donc pas eu de problèmes majeurs. Il existe depuis près de 10 ans depuis la sortie de Sphinx.

Modifications apportées à 1.4.7

https://github.com/sphinx-doc/sphinx/issues/2856

Un PROBLÈME a été enregistré. Si vous ne trouvez pas le mot `` code PIN ''. En Python, il est divisé en code PIN et code et entré dans l'index. Puisqu'il n'y a pas d'espace dans l'expression canonique JavaScript, je rechercherai par code PIN. Bien sûr, la façon dont les mots sont divisés est différente, donc ce sera "index non trouvé". A ce moment, j'ai remarqué pour la première fois que les expressions régulières sont différentes du côté Python et du côté JavaScript.

Si vous créez un index de recherche en Python et effectuez une recherche en JavaScript, les deux doivent être le même prétraitement.

Pour le moment, j'ai changé le côté JavaScript en / \ W + / `` afin de le faire correspondre avec Python.

http://docs.python.jp/3/library/re.html#re.ASCII

En regardant ici, il est dit que ? (U) '' est ignoré dans le contexte unicode et reste uniquement pour la compatibilité descendante. Pourquoi, si vous voulez laisser le drapeau pour compatibilité descendante, pourquoi avez-vous perdu le préfixe u de ```u "Chaîne Unicode" `..., mais si vous n'en avez pas besoin, supprimez-le, JS Le côté est simplement '' / \ w / ``. En fait, c'était un échec ...

Problèmes signalés depuis la version 1.4.7

https://github.com/sphinx-doc/sphinx/issues/3150

Signaler qu'il n'est plus possible de rechercher en chinois (ou en kanji). Quand je l'ai recherché, ça ressemblait à ça.

Langue Expressions régulières Personnages correspondants
Python 2.x r'\w' [a-zA-Z0-9_]
Python 2.x r'\w(?u)' Tout ce qui est considéré comme un caractère en Unicode(Kanji Hiragana)
Python 3.x r'\w' Tout ce qui est considéré comme un caractère en Unicode(Kanji Hiragana)
JavaScript /\w/ [a-zA-Z0-9_]

En d'autres termes, avec JavaScript, `` / \ w / '' ne correspond pas aux kanji. D'après l'histoire que j'ai reçu un rapport plus tard, il semble que les lettres avec tréma étaient également inutiles. En d'autres termes, si vous recherchez des phrases mélangées avec du japonais, la partie japonaise sera complètement supprimée et la recherche sera effectuée. Il est également écrit en MDN Special Character \ b Note.

Ni Python2 ni l'exécution sur une instance d'une chaîne Unicode ne correspondront à autre chose que a-zA-Z0-9_ dans la plage de code ASCII. (? U) n'était pas un bonus. C'est inattendu ...

Il doit être corrigé.

Pour reproduire r '\ w (? U)' en JavaScript

Quand je l'ai essayé en boucle du côté Python, lorsque je correspondais à r '\ w (? U)' ', il y avait 50000 correspondances pour UTF-16 (environ 650000 codes de caractères). C'est plus proche. Même si vous créez une expression régulière avec quelques opposés (ne correspond pas), vous ne pouvez pas l'énumérer au format \ uhhhh```. est.

Mieux encore, vous pouvez avoir le résultat d'une correspondance dans tout le code sous forme de tableau et l'utiliser pour reproduire le même résultat que Python. Rien ne doit être pareil à la logique. Si la fonction est une boîte noire, l'intérieur peut être une base de données, à condition que toutes les sorties soient exactes pour toutes les entrées.

Le code ci-dessous en est le résultat. Il a été fusionné plus tôt et sera corrigé dans la version 1.4.9.

var splitChars = (function() {
    var result = {};
    var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648,
         1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702,
         2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971,
         2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345,
         3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761,
         3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823,
         4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125,
         8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695,
         11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587,
         43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141];
    var i, j, start, end;
    for (i = 0; i < singles.length; i++) {
        result[singles[i]] = true;
    }
    var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709],
         [722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161],
         [1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568],
         [1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807],
         [1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047],
         [2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383],
         [2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450],
         [2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547],
         [2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673],
         [2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820],
         [2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946],
         [2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023],
         [3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173],
         [3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332],
         [3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481],
         [3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718],
         [3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791],
         [3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095],
         [4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205],
         [4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687],
         [4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968],
         [4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869],
         [5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102],
         [6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271],
         [6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592],
         [6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822],
         [6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167],
         [7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959],
         [7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143],
         [8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318],
         [8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483],
         [8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101],
         [10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567],
         [11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292],
         [12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444],
         [12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783],
         [12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311],
         [19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511],
         [42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774],
         [42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071],
         [43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263],
         [43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519],
         [43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647],
         [43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967],
         [44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295],
         [57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274],
         [64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007],
         [65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381],
         [65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]];
    for (i = 0; i < ranges.length; i++) {
        start = ranges[i][0];
        end = ranges[i][1];
        for (j = start; j <= end; j++) {
            result[j] = true;
        }
    }
    return result;
})();
function splitQuery(query) {
    var result = [];
    var start = -1;
    for (var i = 0; i < query.length; i++) {
        if (splitChars[query.charCodeAt(i)]) {
            if (start !== -1) {
                result.push(query.slice(start, i));
                start = -1;
            }
        } else if (start === -1) {
            start = i;
        }
    }
    if (start !== -1) {
        result.push(query.slice(start));
    }
    return result;
}

La liste des codes de caractères dans les singles / plages (simple est un code unique, plages est la plage spécifiée entière) est créée comme suit. Le pictogramme étant une paire de substitution, il est composé de deux caractères, mais les deux ne sont pas valides si un seul caractère est retiré. Cette plage est exclue à l'avance afin qu'elle ne devienne pas un saut de mot.

match = re.compile(r'\w(?u)')
begin = -1

ranges = []
singles = []

for i in range(65536):
    # 0xd800-0xdfff is surrogate pair area. skip this.
    if not match.match(six.unichr(i)) and not (0xd800 <= i <= 0xdfff):
        if begin == -1:
            begin = i
    elif begin != -1:
        if begin + 1 == i:
            singles.append(begin)
        else:
            ranges.append((begin, i - 1))
        begin = -1

Certains d'entre vous peuvent avoir des problèmes comme celui-ci, comme ceux qui essaient de porter des systèmes de traitement Python, PHP ou Ruby vers JavaScript, mais il a été dit qu'il serait tout à fait possible de le faire.

Recommended Posts

Reproduire l'expression canonique Python r '\ w (? U)' en JavaScript
Expression régulière en Python
Match de début / fin dans l'expression régulière python
Nom de groupe symbolique d'expression régulière en Python / Ruby
Expression régulière dans regex.h
mémo d'expression régulière python
L'histoire de FileNotFound en Python open () mode = 'w'
Reproduire l'exemple d'exécution du chapitre 4 de Hajipata en Python
Reproduire l'exemple d'exécution du chapitre 5 de Hajipata en Python
Je veux utiliser le jeu de données R avec python
Utiliser l'expression let en Python
Trouver des erreurs en Python
Notes sur l'expression régulière de la théorie Python
Python --Trouvez le nombre de groupes dans l'expression regex
Générer une distribution U en Python
Manipulation d'expressions régulières par Python
Comment obtenir toutes les valeurs possibles dans une expression régulière
Obtenir l'API arXiv en Python
Python dans le navigateur: la recommandation de Brython
Enregistrez le fichier binaire en Python
Frappez l'API Sesami en Python
Exécutez la commande shell / Python dans R
Obtenez le chemin du bureau en Python
Obtenez le chemin du script en Python
Dans la commande python, python pointe vers python3.8
Implémenter le modèle Singleton en Python
Hashing de données en R et Python
Accédez à l'API Web en Python
J'ai écrit la file d'attente en Python
Calculer le mois précédent en Python
Examiner la classe d'un objet avec python
Obtenez le chemin du bureau en Python
Accéder à l'API Twitter avec Python
La première étape de Python Matplotlib
Lors de l'utilisation d'expressions régulières en Python
J'ai écrit la pile en Python
Maîtriser le module lowref en Python
Fonction Eval () qui calcule une chaîne de caractères comme expression en python
Chevauchement d'expressions régulières en Python et Java
Apprenez le modèle de conception "Prototype" avec Python
Qu'y a-t-il dans le paramètre? Modifier la chaîne et l'expression
Apprenez le modèle de conception "Builder" avec Python
Charger le SDK Python distant avec IntelliJ
Différence d'authenticité entre Python et JavaScript
Utiliser l'impression dans l'expression lambda Python2
Essayez d'utiliser l'API Wunderlist en Python
Vérifiez le comportement du destroyer en Python
Apprenez le modèle de conception "Flyweight" en Python
Essayez d'utiliser l'API Kraken avec Python
Apprenez le modèle de conception "Observer" en Python
Apprenez le modèle de conception "Memento" avec Python
Apprenez le modèle de conception "Proxy" en Python
Ecrire le test dans la docstring python
Rendement Python express en JavaScript ou Java
Apprenez le modèle de conception "Commande" en Python
Prenez la somme logique de List en Python (fonction zip)
Afficher Python 3 dans le navigateur avec MAMP