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.
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.
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 ...
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.
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