Během posledních několika let jsem příležitostně komentoval JavaScriptové RegExp API, syntaxi a chování na ES-Discuss mailing listu. Nedávno vynálezce JavaScriptu Brendan Eich navrhl, abych v zájmu rozproudění diskuse sepsal seznam změn regulárních výrazů, které je třeba vzít v úvahu pro budoucí standardy ECMAScript (nebo, jak to vtipně řekl, mít svých „95 [regulárních] tezí přibitých na Dveře katedrály ES3“). Myslel jsem, že to zkusím, ale svou odpověď rozdělím do několika částí. V tomto příspěvku budu diskutovat o problémech s aktuálním RegExp API a chováním. Nechám stranou nové funkce, které bych rád přidal, a pouze navrhnu způsoby, jak stávající funkce vylepšit. O možných nových funkcích budu diskutovat v následném příspěvku.
U jazyka tak široce používaného, jako je JavaScript, musí jakýkoli realistický návrh změny silně zvážit zpětnou kompatibilitu. Z tohoto důvodu některé z následujících návrhů nemusí být obzvláště realistický, ale přesto si myslím, že a ) stojí za to zvážit, co by se mohlo změnit, pokud by zpětná kompatibilita nebyla problémem, a b ) z dlouhodobého hlediska by všechny tyto změny zlepšily snadnost použití a předvídatelnost fungování regulárních výrazů v JavaScriptu.
Odeberte RegExp.prototype.lastIndex a nahraďte jej argumentem pro počáteční pozici
Skutečný návrh:Ukončete podporu RegExp.prototype.lastIndex a přidejte argument "pos" do metod RegExp.prototype.exec/test
05
JavaScriptu vlastnost slouží příliš mnoha účelům najednou:
- Umožňuje uživatelům ručně určit, kde začít hledání podle regulárního výrazu
- Mohli byste tvrdit, že to není
17
's zamýšlený účel, ale je to přesto důležité použití, protože neexistuje žádná alternativní funkce, která by to umožňovala.29
není v tomto úkolu příliš dobrý. Musíte zkompilovat svůj regulární výraz s36
příznak nechat46
být používán tímto způsobem; a dokonce i poté určuje pouze počáteční pozici pro53
/61
metody. Nelze jej použít k nastavení počáteční pozice pro76
/80
/93
/106
metody. - Označuje pozici, kde skončil poslední zápas
- I když byste mohli odvodit koncovou pozici shody přidáním indexu shody a délky, toto použití
112
slouží jako pohodlný a běžně používaný doplněk k125
vlastnost na odpovídajících polích vrácených133
. Jako vždy pomocí143
takto funguje pouze pro regulární výrazy kompilované s158
. - Používá se ke sledování pozice, kde by mělo začít další vyhledávání
- To přichází v úvahu například při použití regulárního výrazu k iteraci všech shod v řetězci. Nicméně skutečnost, že
166
je ve skutečnosti nastaveno na koncovou pozici poslední shody spíše než na pozici, kde by mělo začít další hledání (na rozdíl od ekvivalentů v jiných programovacích jazycích), způsobuje problém po shodách s nulovou délkou, které jsou snadno možné u regulárních výrazů jako176
nebo184
. Proto jste nuceni ručně zvýšit198
v takových případech. O tomto problému jsem již dříve psal podrobněji (viz:Chyba IE lastIndex s nulovou délkou shod regulárního výrazu ), stejně jako Jan Goyvaerts (Pozor na zápasy s nulovou délkou ).
Bohužel 207
Všestrannost má za následek, že nefunguje ideálně pro žádné konkrétní použití. Myslím, že 212
je stejně špatně umístěn; pokud potřebujete uložit koncovou (nebo příští-start) pozici vyhledávání, měla by to být vlastnost cílového řetězce a ne regulárního výrazu. Zde jsou tři důvody, proč by to fungovalo lépe:
- Umožnilo by vám to použít stejný regulární výraz s více řetězci, aniž byste ztratili přehled o další pozici vyhledávání v každém z nich.
- Umožnilo by to používat více regulárních výrazů se stejným řetězcem a každý z nich by navázal od místa, kde skončil poslední.
- Pokud hledáte dva řetězce se stejným regulárním výrazem, pravděpodobně neočekáváte, že hledání v druhém řetězci začne z libovolné pozice jen proto, že byla nalezena shoda v prvním řetězci.
Ve skutečnosti Perl používá tento přístup ukládání pozic dalšího hledání s řetězci s velkým efektem a přidává kolem něj různé funkce.
Takže to je můj případ pro 226
je špatně umístěn, ale jdu ještě dále v tom, že si nemyslím, že 231
by měl být v JavaScriptu vůbec zahrnut. Taktika Perlu funguje dobře pro Perl (zejména když je považována za kompletní balíček), ale některé další jazyky (včetně Pythonu) vám umožňují zadat počáteční pozici vyhledávání jako argument při volání metod regulárních výrazů, což je podle mého názoru přirozenější přístup. a snazší pro vývojáře k pochopení a použití. Proto bych opravil 242
tím, že se ho úplně zbavíte. Metody regulárního výrazu a metody řetězců používající regulární výraz by používaly interní sledovače pozic vyhledávání, které uživatel nepozoruje, a 251
a 263
metody by dostaly druhý argument (nazvaný 274
, pro pozici), která určuje, kde má začít hledání. Může být vhodné zadat také 287
metody 291
, 301
, 313
a 325
jejich vlastní 334
argumenty, ale to není tak důležité a funkce, které by poskytovaly, nejsou v současné době možné prostřednictvím 340
každopádně.
Níže jsou uvedeny příklady některých běžných použití 353
by mohl být přepsán, pokud byly provedeny tyto změny:
Začněte hledat od pozice 5 pomocí 366
(status quo):
var regexGlobal = /\w+/g, result; regexGlobal.lastIndex = 5; result = regexGlobal.test(str); // must reset lastIndex or future tests will continue from the // match-end position (defensive coding) regexGlobal.lastIndex = 0; var regexNonglobal = /\w+/; regexNonglobal.lastIndex = 5; // no go - lastIndex will be ignored. instead, you have to do this result = regexNonglobal.test(str.slice(5));
Začněte hledat od pozice 5 pomocí 370
:
var regex = /\w+/, // flag /g doesn't matter result = regex.test(str, 5);
Iterace shody pomocí 384
:
var regex = /\w*/g, matches = [], match; // the /g flag is required for this regex. if your code was provided a non- // global regex, you'd need to recompile it with /g, and if it already had /g, // you'd need to reset its lastIndex to 0 before entering the loop while (match = regex.exec(str)) { matches.push(match); // avoid an infinite loop on zero-length matches if (regex.lastIndex == match.index) { regex.lastIndex++; } }
Iterace shody pomocí 393
:
var regex = /\w*/, // flag /g doesn't matter pos = 0, matches = [], match; while (match = regex.exec(str, pos)) { matches.push(match); pos = match.index + (match[0].length || 1); }
Samozřejmě můžete snadno přidat svůj vlastní cukr pro další zjednodušení iterace shody, nebo by JavaScript mohl přidat metodu vyhrazenou pro tento účel podobnou Ruby's 401
(ačkoli JavaScript už to tak nějak má díky použití náhradních funkcí s 417
).
Abych to zopakoval, popisuji, co bych dělal, kdyby byla zpětná kompatibilita irelevantní. Nemyslím si, že by bylo dobré přidat 428
argument do 439
a 448
kromě 459
vlastnost byla zastaralá nebo odstraněna z důvodu překrývání funkcí. Pokud 466
argument existoval, lidé by očekávali 475
být 486
když to není určeno. S 492
někdy pokazit toto očekávání by bylo matoucí a pravděpodobně by vedlo k latentním chybám. Pokud tedy 505
byla ukončena podpora ve prospěch 515
, měl by to být prostředek ke konci odstranění 528
celkem.
Odstranění neglobálního provozního režimu String.prototype.match
Skutečný návrh:Ukončete podporu String.prototype.match a přidejte novou metodu matchAll
538
aktuálně funguje velmi odlišně v závislosti na tom, zda 549
(globální) příznak byl nastaven na zadaný regulární výraz:
- Pro regulární výrazy s
557
:Pokud nebyly nalezeny žádné shody,562
je vrácen; jinak se vrátí pole jednoduchých shod. - Pro regulární výrazy bez
575
:584
metoda funguje jako alias591
. Pokud shoda není nalezena,607
je vrácen; jinak získáte pole obsahující (jedinou) shodu v klíči nula, se všemi zpětnými referencemi uloženými v následujících klíčích pole. Pole je také přiřazeno speciální618
a621
vlastnosti.
637
neglobální režim metody je matoucí a zbytečný. Důvod, proč je to zbytečné, je zřejmý:Pokud chcete funkcionalitu 648
, stačí jej použít (není potřeba alias). Je to matoucí, protože, jak je popsáno výše, 651
dva režimy metody vracejí velmi odlišné výsledky. Rozdíl není pouze v tom, zda získáte jeden zápas nebo všechny zápasy – získáte úplně jiný druh výsledku. A protože výsledkem je v obou případech pole, musíte znát stav 662
regulárního výrazu vlastnost, abyste věděli, se kterým typem pole máte co do činění.
Změnil bych 677
tím, že vždy vrátí pole obsahující všechny shody v cílovém řetězci. Také bych udělal, aby vracelo prázdné pole místo 689
, když nebyly nalezeny žádné shody (nápad, který pochází z knihovny base2 Deana Edwardse). Pokud chcete pouze první shodu nebo potřebujete zpětné reference a další podrobnosti o shodě, je to 697
je pro.
Bohužel, pokud chcete tuto změnu považovat za realistický návrh, vyžadovalo by to nějaký druh jazykové verze nebo přepnutí režimu 704
chování metody (myslím, že se to pravděpodobně nestane). Takže místo toho bych doporučil zavrhnout 719
metoda zcela ve prospěch nové metody (možná 724
) se změnami předepsanými výše.
Zbavte se /g a RegExp.prototype.global
Skutečný návrh:Ukončete podporu /g a RegExp.prototype.global a do String.prototype.replace přidejte booleovský argument replaceAll
Pokud byly implementovány poslední dva návrhy a tedy 733
a 749
byly věci minulosti (nebo 755
již někdy nesloužil jako alias 769
), jediná metoda, kde je 776
bude mít stále nějaký dopad je 787
. Navíc, ačkoli 792
navazuje na předchozí umění z Perlu atd., ve skutečnosti nedává smysl mít něco, co není atributem regulárního výrazu, uloženo jako příznak regulárního výrazu. Opravdu, 807
je spíše prohlášení o tom, jak chcete, aby metody aplikovaly svou vlastní funkčnost, a není neobvyklé chtít použít stejný vzor s 819
a bez něj (aktuálně byste k tomu museli vytvořit dva různé regulární výrazy). Kdyby to bylo na mně, zbavil bych se 828
příznak a jeho odpovídající 831
vlastnost a místo toho jednoduše zadejte 841
metoda další argument, který označuje, zda chcete nahradit pouze první shodu (výchozí zpracování) nebo všechny shody. To lze provést buď pomocí 855
boolean nebo pro lepší čitelnost 869
řetězec, který přijímá hodnoty 874
a 882
. Tento nový argument by měl další výhodu v tom, že by umožnil nahradit všechny funkce hledáním bez regulárního výrazu.
Všimněte si, že SpiderMonkey již má proprietární třetí 892
argument ("vlajky"), se kterým by byl tento návrh v rozporu. Pochybuji, že by tento konflikt způsobil velké pálení žáhy, ale v každém případě nový 904
argument by poskytoval stejnou funkcionalitu jako SpiderMonkey 917
argument je nejužitečnější pro (to znamená, že umožňuje globální nahrazení hledáním bez regulárního výrazu).
Změňte chování zpětných referencí na nezúčastněné skupiny
Skutečný návrh:Zpětné odkazy na nezúčastněné skupiny se neshodují
Zůstanu stručný, protože jsme s Davidem „lioreanem“ Anderssonem o to dříve argumentovali na ES-Discuss a jinde. David o tom podrobně psal na svém blogu (viz:ECMAScript 3 Regular Expressions:Specifikace, která nedává smysl ), a již jsem se toho dotkl zde (Regulární výrazy ECMAScript 3 jsou vadné již podle návrhu ). Při několika příležitostech Brendan Eich také prohlásil, že by rád viděl, aby se to změnilo. Krátké vysvětlení tohoto chování je, že v JavaScriptu jsou zpětné odkazy na zachycení skupin, které se (zatím) zápasu neúčastnily, vždy úspěšné (tj. shodují se s prázdným řetězcem), zatímco opak je pravdou ve všech ostatních variantách regulárních výrazů:selžou, a proto způsobí, že motor regulárních výrazů ustoupí nebo selže. Chování JavaScriptu znamená, že 920
vrátí 934
. (Negativní) důsledky toho sahají poměrně daleko při posouvání hranic regulárních výrazů.
Myslím, že všichni souhlasí s tím, že změna na tradiční chování zpětných odkazů by byla zlepšením – poskytuje mnohem intuitivnější ovládání, kompatibilitu s jinými příchutěmi regulárních výrazů a velký potenciál pro kreativní využití (např. viz můj příspěvek na Napodobování podmínek ). Větší otázkou je, zda by to bylo bezpečné ve světle zpětné kompatibility. Myslím, že by bylo, protože si představuji, že víceméně nikdo nepoužívá neintuitivní chování JavaScriptu záměrně. Chování JavaScriptu se rovná automatickému přidávání 942
kvantifikátor po zpětných referencích na nezúčastněné skupiny, což lidé již explicitně dělají, pokud skutečně chtějí, aby byly zpětné reference na podvzorce nenulové délky volitelné. Všimněte si také, že Safari 3.0 a dřívější nedodržovaly specifikace v tomto bodě a používaly intuitivnější chování, i když to se v novějších verzích změnilo (zejména tato změna byla způsobena zápisem na mém blogu spíše než zprávami o skutečných- světové chyby).
A konečně, pravděpodobně stojí za zmínku, že režim regulárního výrazu ECMAScript .NET (aktivovaný pomocí 954
flag) skutečně přepne .NET na nekonvenční chování zpětných odkazů ECMAScript.
Zajistěte, aby \d \D \w \W \b \B podporovalo Unicode (jako \s \S . ^ $, které již podporuje)
Skutečný návrh:Přidejte příznak /u (a odpovídající vlastnost RegExp.prototype.unicode), která mění význam \d, \w, \b a souvisejících tokenů
Porovnávání znaků s číslicemi a slovy s podporou Unicode není existující schopností JavaScriptu (nestačí vytvářet nestvůry znakových tříd, které jsou dlouhé stovky nebo tisíce znaků), a protože JavaScript postrádá pohled do pozadí, nemůžete reprodukovat hranici slova s podporou Unicode. Dalo by se tedy říci, že tento návrh je mimo uvedený rozsah tohoto příspěvku, ale uvádím jej zde, protože to považuji spíše za opravu než za novou funkci.
Podle aktuálních standardů JavaScriptu 968
, 977
, 983
, 993
a 1009
používat interpretace mezera založené na Unicode a nový řádek , zatímco 1013
, 1024
, 1036
, 1044
, 1050
a 1062
používejte pouze ASCII interpretace číslice , znak slova a hranice slova (např. 1072
bohužel vrací 1081
). Viz můj příspěvek na JavaScript, Regex a Unicode pro další detaily. Přidání podpory Unicode do těchto tokenů by způsobilo neočekávané chování pro tisíce webů, ale mohlo by být bezpečně implementováno pomocí nového 1092
vlajka (inspirovaná Pythonovým 1107
nebo 1118
příznak) a odpovídající 1120
vlastnictví. Protože je ve skutečnosti docela běžné ne chcete, aby tyto tokeny měly povoleno Unicode v konkrétních vzorech regulárních výrazů, nový příznak, který aktivuje podporu Unicode, by nabídl to nejlepší z obou světů.
Změnit chování resetování zpětné reference během opakování dílčího vzoru
Skutečný návrh:Nikdy neresetujte zpětné referenční hodnoty během zápasu
Stejně jako poslední problém se zpětnou referencí, i toto řešil David Andersson ve svém příspěvku ECMAScript 3 Regular Expressions:Specifikace, která nedává smysl . Problém se zde týká hodnoty, kterou si pamatuje zachycení skupin vnořených do kvantifikované vnější skupiny (např. 1135
). Podle tradičního chování je hodnota, kterou si zachycující skupina v rámci kvantifikovaného seskupení zapamatuje, jakákoliv, s jakou se skupina shodovala při poslední účasti v zápase. Takže hodnota 1148
po 1158
se používá pro shodu s 1161
bude 1172
. Podle ES3/ES5 je však hodnota zpětných referencí na vnořená seskupení resetována/vymazána po zopakování vnějšího seskupení. Proto 1182
bude stále odpovídat 1190
, ale po dokončení shody 1205
by odkazovalo na nezúčastněnou zachytávací skupinu, která by v JavaScriptu odpovídala prázdnému řetězci v samotném regulárním výrazu a byla by vrácena jako 1218
např. v poli vráceném 1227
.
Můj případ pro změnu spočívá v tom, že současné chování JavaScriptu se vymyká standardu v jiných variantách regulárních výrazů a nehodí se k různým typům kreativních vzorců (viz jeden příklad v mém příspěvku na téma Zachycení více, volitelné hodnoty atributu HTML ), a podle mého názoru je mnohem méně intuitivní než běžnější alternativní chování regulárních výrazů.
Věřím, že toto chování je bezpečné změnit ze dvou důvodů. Za prvé, toto je obecně problém okrajového případu pro všechny, kromě hardcore mágů s regulárními výrazy, a byl bych překvapen, kdybych našel regulární výrazy, které se spoléhají na verzi tohoto chování v JavaScriptu. Za druhé, a co je důležitější, Internet Explorer toto pravidlo neimplementuje a řídí se tradičnějším chováním.
Přidat příznak /s již
Skutečný návrh:Přidejte příznak /s (a odpovídající vlastnost RegExp.prototype.dotall), která změní tečku tak, aby odpovídala všem znakům včetně nových řádků
Tuto funkci vložím spíše jako změnu/opravu než jako novou funkci, protože použití 1234
není zrovna obtížné místo tečky, když chcete chování 1240
. Předpokládám 1251
flag byl doposud vyloučen, aby se zachránili nováčci před nimi samými a omezily se škody způsobené únikovým backtrackingem, ale nakonec se stane to, že lidé píší strašně neefektivní vzory jako 1265
místo toho.
Vyhledávání podle regulárních výrazů v JavaScriptu je jen zřídka založené na řádcích, a proto je běžnější chtít, aby tečka zahrnovala nové řádky, než aby odpovídala čemukoli jinému než nové řádky (ačkoli oba režimy jsou užitečné). Je rozumné ponechat výchozí význam tečky (žádné nové řádky), protože ji sdílejí jiné varianty regulárních výrazů a je vyžadována pro zpětnou kompatibilitu, ale přidáním podpory pro 1270
vlajka je po splatnosti. Logická hodnota označující, zda byl tento příznak nastaven, by se měla zobrazit v regulárních výrazech jako vlastnost s názvem buď 1281
(nešťastné jméno z Perlu, .NET atd.) nebo popisnější 1294
(používá se v Javě, Pythonu, PCRE atd.).
Osobní preference
Následuje několik změn, které by vyhovovaly mým preferencím, i když si nemyslím, že by je většina lidí považovala za významné problémy:
- Povolit literály regulárních výrazů používat lomítka bez speciálních znaků v rámci tříd znaků (např.
1303
). To již bylo zahrnuto v opuštěných návrzích změn ES4. - Povolit
1310
bez kódování znaků jako první znak ve třídách znaků (např.1322
nebo1337
). To je povoleno pravděpodobně v každé jiné variantě regulárního výrazu, ale vytvoří prázdnou třídu následovanou doslovným1347
v JavaScriptu. Rád bych si představil, že nikdo nepoužívá prázdné třídy záměrně, protože nefungují konzistentně napříč prohlížeči a existují široce používané alternativy se zdravým rozumem (1352
místo1364
a1376
místo1382
). Bohužel, dodržování této zvláštnosti JavaScriptu je testováno v Acid3 (test 89), což je pravděpodobně dost na to, aby zabilo požadavky na tuto zpětně nekompatibilní, ale rozumnou změnu. - Změňte
1396
token používaný v náhradních řetězcích na1402
. Prostě to dává smysl. (Ekvivalenty v jiných variantách nahrazujícího textu pro srovnání:Perl:1416
; Java:1420
; .NET:1435
,1440
; PHP:1452
,1461
; Ruby:1474
,1481
; Python:1495
.) - Zbavte se zvláštního významu
1502
. V rámci znakových tříd je to metasekvence1514
odpovídá znaku backspace (ekvivalent1526
). To je zbytečné pohodlí, protože nikoho nezajímá shoda znaků backspace a je to matoucí vzhledem k tomu, že1535
odpovídá hranici slova při použití mimo třídy znaků. I když by to narušilo tradici regulárního výrazu (kterou bych obvykle obhajoval, myslím si, že1547
by neměl mít žádný zvláštní význam uvnitř tříd znaků a jednoduše odpovídat doslovnému1550
.
Opraveno v ES3:Odstraňte odkazy na osmičkové znaky
ECMAScript 3 odstranil odkazy na osmičkové znaky ze syntaxe regulárního výrazu, ačkoli 1563
byl zachován jako výhodná výjimka, která umožňuje snadné porovnání znaku NUL. Prohlížeče si však obecně udržují plnou osmičkovou podporu kvůli zpětné kompatibilitě. Osmičkové soustavy jsou v regulárních výrazech velmi matoucí, protože jejich syntaxe se překrývá se zpětnými odkazy a mimo třídy znaků je povolena další úvodní nula. Zvažte následující regulární výrazy:
1575
:1585
je osmičkový.1597
:1601
je zpětná reference.1610
:1626
je osmičkový.1636
:1643
je zpětná reference;1654
je osmičkový.1667
:Všechny výskyty1679
a1687
jsou osmičkové. Podle specifikací ES3+ však čísla za každým1693
by mělo být zacházeno (s výjimkou nestandardních rozšíření) jako doslovné znaky, které zcela mění to, čemu tento regulární výraz odpovídá. (Edit-2012:Ve skutečnosti podrobné přečtení specifikace ukazuje, že jakákoli 0-9 následující za1702
by měl způsobit1712
.)1722
:1733
mimo třídu znaků je osmička; ale uvnitř osmička končí třetí nulou (tj. třída znaků odpovídá indexu znaku nula nebo1740
). Tento regulární výraz je tedy ekvivalentní1751
; ačkoli, jak bylo zmíněno výše, dodržování ES3 by změnilo význam.1763
:Mimo třídu znaků osmičkové číslo končí čtvrtou nulou a následuje doslovný1776
. Uvnitř osmička končí na třetí nule a následuje doslovný1781
. A ještě jednou, ES3 vyloučení oktalů a zahrnutí1791
mohl změnit význam.1804
:Vzhledem k tomu, že v JavaScriptu zpětné odkazy na zachycující skupiny, které se (zatím) neúčastnily, odpovídají prázdnému řetězci, odpovídá tento regulární výraz1812
(tj.1823
se považuje za zpětnou referenci, protože se v regulárním výrazu objevuje odpovídající skupina zachycení) nebo odpovídá1831
(tj.1846
se považuje za osmičkovou, protože se objevuje před jeho odpovídající skupina)? Není překvapením, že prohlížeče nesouhlasí.1851
:Teď jsou věci opravdu chlupaté. Odpovídá tento regulární výraz1867
? ,1877
,1883
,1891
,1905
nebo1913
? Všechny tyto možnosti se zdají věrohodné a prohlížeče se na správné volbě neshodnou.
Existují také další problémy, kterých je třeba se obávat, například zda osmičkové znaky jdou až do 1922
(1934
, 8bitové) nebo 1946
(1953
, 9-bit); ale v každém případě jsou osmičky v regulárních výrazech matoucí cluster-cuss. Přestože ECMAScript již tento nepořádek vyčistil odstraněním podpory pro osmičkové číslice, prohlížeče jej nenásledovaly. Kéž by to udělali, protože na rozdíl od výrobců prohlížečů se o tento kousek dědictví nemusím starat (nikdy nepoužívám osmičkové soustavy v regulárních výrazech a ani vy byste neměli).
Opraveno v ES5:Neukládat do mezipaměti literály regulárních výrazů
Podle pravidel ES3 nevytvářely literály regulárních výrazů nový objekt regulárních výrazů, pokud byl literál se stejnou kombinací vzor/příznak již použit ve stejném skriptu nebo funkci (toto se nevztahuje na regulární výrazy vytvořené kódem 1963
konstruktér). Častým vedlejším efektem bylo, že literály regulárních výrazů používají 1970
vlajka neměla svůj 1980
vlastnost reset v některých případech, kdy by to většina vývojářů očekávala. Několik prohlížečů nedodrželo specifikaci tohoto neintuitivního chování, ale Firefox ano, a v důsledku toho se stal druhým nejvíce duplicitním hlášením o chybě JavaScriptu pro Mozillu. Naštěstí se ES5 tohoto pravidla zbavilo a nyní je nutné literály regulárních výrazů překompilovat pokaždé, když na ně narazíte (tato změna přichází ve Firefoxu 3.7).
———
Tak tady to máte. Nastínil jsem, co si myslím, že JavaScript RegExp API udělalo chybu. Souhlasíte se všemi těmito návrhy, nebo bych vy, kdybyste se nemuseli starat o zpětnou kompatibilitu? Existují lepší způsoby než ty, které jsem navrhoval, jak vyřešit problémy zde diskutované? Máte nějaké další výhrady k existujícím funkcím regulárního výrazu JavaScriptu? Těším se na zpětnou vazbu.
Protože jsem se v tomto příspěvku zaměřil na negativa, poznamenám, že práci s regulárními výrazy v JavaScriptu považuji za obecně příjemnou zkušenost. JavaScriptu je toho zatraceně hodně.