Reproduzieren Sie den regulären Python-Ausdruck r '\ w (? U)' in JavaScript

Die Kompatibilität regulärer Ausdrücke zwischen Sprachen ist ein schwieriges Problem. Als ich vor langer Zeit den Ruby-Interpreter in Python implementierte, bezog ich mich auf den Ruby-Parser von Ruby, konnte ihn aber nicht gut portieren und keinen vollständigen Parser erstellen. Das ist gut.

Ich hatte einen Fehlerbericht über Sphinx und bin erneut auf ein Kompatibilitätsproblem mit regulären Ausdrücken gestoßen, aber ich werde eine Notiz darüber hinterlassen, da einige Leute in anderen Sprachen möglicherweise Probleme mit dem Problem haben.

Umstände der Sphinx

Sphinx ist ein Dokumentgenerator, der statisches HTML generiert. Sie können PDF über Latex und verschiedene Ausgaben wie texinfo und man ausgeben. Nun, wahrscheinlich ist HTML das am häufigsten verwendete. Der charakteristische Punkt der HTML-Ausgabe besteht darin, einen Suchindex in Python zu erstellen und ihn zu JSON zu machen. Der Browser liest den JSON und sucht.

In Python werden Suchbegriffe erstellt, indem Sätze nach bestimmten Regeln in Wörter unterteilt werden. Selbst in JavaScript wird nach der Aufteilung der Suchbegriffe in Wörter die Suche mit dem auf der Python-Seite erstellten Wörterbuch durchgeführt.

JavaScript hat die Wortteilung mit dem folgenden regulären Ausdruck durchgeführt

/\s+/

Python verwendete die folgenden regulären Ausdrücke als übereinstimmende Wörter.

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

In beiden Fällen erlauben Leerzeichenbegrenzer Wortbegrenzer, sodass keine größeren Probleme auftraten. Es gibt es seit fast 10 Jahren seit der Veröffentlichung von Sphinx.

Änderungen in 1.4.7

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

Eine AUSGABE wurde registriert. Wenn die Zeichen `PIN-Code `nicht gesucht werden können. In Python wird es in PIN und Code unterteilt und in den Index eingetragen. Da der kanonische JavaScript-Ausdruck kein Leerzeichen enthält, werde ich nach PIN-Code suchen. Natürlich ist die Art und Weise, wie die Wörter geteilt werden, unterschiedlich, daher wird es "Index nicht gefunden" sein. Zu diesem Zeitpunkt bemerkte ich zum ersten Mal, dass die regulären Ausdrücke auf der Python-Seite und der JavaScript-Seite unterschiedlich sind.

Wenn Sie einen Suchindex in Python erstellen und in JavaScript suchen, müssen beide dieselbe Vorverarbeitung sein.

Vorerst habe ich die JavaScript-Seite in `/ \ W + /` geändert, um sie mit Python abzugleichen.

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

Hier wird angegeben, dass `? (U)` im Unicode-Kontext ignoriert wird und nur aus Gründen der Abwärtskompatibilität verbleibt. Warum, wenn Sie das Flag aus Gründen der Abwärtskompatibilität belassen möchten, warum haben Sie das u-Präfix von `u" Unicode-Zeichenfolge "` einmal verloren ... aber wenn Sie es nicht benötigen, löschen Sie es, JS Die Seite ist einfach `/ \ w /`. Eigentlich war das ein Misserfolg ...

Seit der Version 1.4.7 gemeldete Probleme

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

Berichten Sie, dass es nicht mehr möglich ist, auf Chinesisch (oder Kanji) zu suchen. Als ich es nachgeschlagen habe, sah es so aus.

Sprache Reguläre Ausdrücke Übereinstimmende Zeichen
Python 2.x r'\w' [a-zA-Z0-9_]
Python 2.x r'\w(?u)' Alles, was in Unicode als Zeichen betrachtet wird(Hiragana Kanji)
Python 3.x r'\w' Alles, was in Unicode als Zeichen betrachtet wird(Hiragana Kanji)
JavaScript /\w/ [a-zA-Z0-9_]

Mit anderen Worten, mit JavaScript stimmt `/ \ w /` nicht mit Kanji überein. Nach der Geschichte, die ich später erhalten habe, scheinen die Buchstaben mit Umlaut auch nutzlos zu sein. Mit anderen Worten, wenn Sie nach Sätzen suchen, die mit Japanisch gemischt sind, wird der japanische Teil vollständig gelöscht und die Suche wird durchgeführt. Es ist auch in MDN-Sonderzeichen \ b Annotation geschrieben.

Weder Python2 noch die Ausführung für eine Instanz einer Unicode-Zeichenfolge stimmen mit etwas anderem als a-zA-Z0-9_ innerhalb des ASCII-Codebereichs überein. `(? U)` war kein Bonus. Das ist unerwartet ...

Es muss behoben werden.

So reproduzieren Sie r '\ w (? U)' in JavaScript

Als ich es tatsächlich versuchte, während ich auf der Python-Seite eine Schleife durchführte, als ich mit "r" \ w (? U) "" übereinstimmte, gab es 50.000 Übereinstimmungen für UTF-16 (ungefähr 650.000 Zeichencodes). Es ist näher. Selbst wenn Sie einen regulären Ausdruck mit ein paar Gegensätzen erstellen (nicht übereinstimmen), können Sie ihn nicht im Format `` \ uhhhh``` aufzählen. Es scheint unmöglich, mit einem regulären Ausdruck damit umzugehen. ist.

Besser noch, Sie können das Ergebnis einer Übereinstimmung im gesamten Code als Array haben und damit das gleiche Ergebnis wie Python reproduzieren. Bis zur Logik muss nichts gleich sein. Wenn es sich bei der Funktion um eine Black Box handelt, kann das Innere eine Datenbank sein, solange alle Ausgaben für alle Eingaben korrekt sind.

Der folgende Code ist das Ergebnis davon. Es wurde früher zusammengeführt und wird in 1.4.9 behoben.

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

Die Liste der Zeichencodes in Singles / Bereichen (Single ist ein einzelner Code, Bereiche ist der gesamte angegebene Bereich) wird wie folgt erstellt. Da das Piktogramm ein Ersatzpaar ist, besteht es aus zwei Zeichen, aber beide sind ungültig, wenn nur ein Zeichen herausgenommen wird. Dieser Bereich wird im Voraus ausgeschlossen, damit es nicht zu einem Wortumbruch kommt.

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

Einige von Ihnen haben möglicherweise solche Probleme, z. B. diejenigen, die versuchen, Python-, PHP- oder Ruby-Verarbeitungssysteme auf JavaScript zu portieren, aber es wurde gesagt, dass dies durchaus möglich wäre.

Recommended Posts

Reproduzieren Sie den regulären Python-Ausdruck r '\ w (? U)' in JavaScript
Regulärer Ausdruck in Python
Start / End-Match im regulären Python-Ausdruck
Symbolischer Gruppenname für reguläre Ausdrücke in Python / Ruby
Regulärer Ausdruck in regex.h
Python-Memo für reguläre Ausdrücke
Die Geschichte von FileNotFound im Python open () -Modus = 'w'
Reproduzieren Sie das Ausführungsbeispiel von Kapitel 4 von Hajipata in Python
Reproduzieren Sie das Ausführungsbeispiel von Kapitel 5 von Hajipata in Python
Ich möchte R-Datensatz mit Python verwenden
Verwenden Sie den let-Ausdruck in Python
Finde Fehler in Python
Python-Theorie regulärer Ausdruck Anmerkungen
Python - Ermitteln Sie die Anzahl der Gruppen im regulären Ausdruck
Generieren Sie eine U-Verteilung in Python
Manipulation regulärer Ausdrücke durch Python
So erhalten Sie alle möglichen Werte in einem regulären Ausdruck
Abrufen der arXiv-API in Python
Python im Browser: Brythons Empfehlung
Speichern Sie die Binärdatei in Python
Klicken Sie in Python auf die Sesami-API
Führen Sie den Shell-Befehl / Python in R aus
Holen Sie sich den Desktop-Pfad in Python
Holen Sie sich den Skriptpfad in Python
Im Python-Befehl zeigt Python auf Python3.8
Implementieren Sie das Singleton-Muster in Python
Hashing von Daten in R und Python
Klicken Sie auf die Web-API in Python
Ich habe die Warteschlange in Python geschrieben
Berechnen Sie den Vormonat in Python
Untersuchen Sie die Klasse eines Objekts mit Python
Holen Sie sich den Desktop-Pfad in Python
Greifen Sie mit Python auf die Twitter-API zu
Der erste Schritt von Python Matplotlib
Bei Verwendung regulärer Ausdrücke in Python
Ich habe den Stack in Python geschrieben
Beherrsche das schwache Ref-Modul in Python
Die eval () -Funktion, die eine Zeichenfolge als Ausdruck in Python berechnet
Überlappende reguläre Ausdrücke in Python und Java
Lernen Sie das Entwurfsmuster "Prototype" mit Python
Was ist in dem Parameter? String & Ausdruck bearbeiten
Lernen Sie das Entwurfsmuster "Builder" mit Python
Laden Sie das Remote-Python-SDK mit IntelliJ
Unterschied in der Authentizität zwischen Python und JavaScript
Verwenden Sie print in Python2 lambda expression
Versuchen Sie es mit der Wunderlist-API in Python
Überprüfen Sie das Verhalten des Zerstörers in Python
Lernen Sie das Designmuster "Flyweight" in Python
Versuchen Sie, die Kraken-API mit Python zu verwenden
Lernen Sie das Entwurfsmuster "Observer" in Python
Lernen Sie das Entwurfsmuster "Memento" mit Python
Lernen Sie das Entwurfsmuster "Proxy" in Python
Schreiben Sie den Test in die Python-Dokumentzeichenfolge
Express Python-Ertrag in JavaScript oder Java
Lernen Sie das Entwurfsmuster "Befehl" in Python
Nehmen Sie die logische Summe von List in Python (Zip-Funktion)
Zeigen Sie Python 3 im Browser mit MAMP an