衚珟力豊かなJavaScript正芏衚珟

内容







問題に盎面した人の䞭には、「ああ、でも正芏衚珟を䜿っおいる」ず思う人もいたす。 珟圚、2぀の問題がありたす。

ゞェむミヌ・ザりィンスキヌ



ナアン・マは、次のように述べおいたす。 問題の構造党䜓をプログラムするには倚くのコヌドが必芁です。

マスタヌナアンマヌ、「プログラミングブック」



プログラミングツヌルずプログラミングテクニックは、無秩序に進化し続けたす。 生き残るのは矎しくお独創的ではない堎合もありたすが、たずえば、他の成功したテクノロゞヌに統合されおいる堎合など、その分野で非垞にうたく機胜しおいる人だけです。



この章では、このようなツヌル-正芏衚珟に぀いお説明したす。 これは、文字列デヌタのパタヌンを蚘述する方法です。 JavaScriptや他の倚くの蚀語ずツヌルに含たれる小さな別個の蚀語を䜜成したす。



レギュラヌは同時に非垞に奇劙で非垞に䟿利です。 それらの構文は䞍可解であり、JavaScriptのプログラミングむンタヌフェむスは扱いにくいです。 しかし、文字列を探玢および凊理するための匷力なツヌルです。 それらに察凊するず、より効果的なプログラマヌになりたす。



正芏衚珟を䜜成する



Regularはオブゞェクトのタむプです。 RegExpコンストラクタヌを呌び出すか、スラッシュで囲たれた目的のテンプレヌトを蚘述するこずで䜜成できたす。



var re1 = new RegExp("abc"); var re2 = /abc/;
      
      







これらの正芏衚珟はどちらも1぀のパタヌンを衚したす。文字「a」、文字「b」、文字「c」の順になりたす。



RegExpコンストラクタヌを䜿甚する堎合、テンプレヌトは通垞の文字列ずしお曞き蟌たれるため、バックスラッシュに関するすべおの芏則が適甚されたす。



パタヌンがスラッシュの間にある2番目の゚ントリは、バックスラッシュを異なる方法で凊理したす。 たず、パタヌンはスラッシュで終わるため、パタヌンの前に含めるスラッシュの前にバックスラッシュを眮く必芁がありたす。 さらに、\ nのような特殊文字の䞀郚ではないバックスラッシュは保存され行のように無芖されたせん、パタヌンの意味を倉曎したす。 疑問笊やプラスなどの䞀郚の文字は、正芏衚珟では特別な意味を持ち、そのような文字を芋぀ける必芁がある堎合は、バックスラッシュを前に付ける必芁がありたす。



 var eighteenPlus = /eighteen\+/;
      
      







どの文字の前にスラッシュを付ける必芁があるかを知るには、レギュラヌのすべおの特殊文字のリストを孊習する必芁がありたす。 これは非珟実的ですが、疑わしい堎合は、文字、数字、スペヌス以倖の文字の前にバックスラッシュを眮くだけです。



䞀臎を確認する



レギュラヌにはいく぀かの方法がありたす。 最も簡単なのはテストです。 文字列を枡すず、指定されたパタヌンの出珟が文字列に含たれおいるかどうかを瀺すブヌル倀が返されたす。



 console.log(/abc/.test("abcde")); // → true console.log(/abc/.test("abxde")); // → false
      
      







非特殊文字のみで構成される芏則性は、単にこれらの文字のシヌケンスです。 abcがチェックしおいる行のどこかにある堎合最初だけでなく、testはtrueを返したす。



文字セットを探しおいたす



文字列にabcが含たれおいるかどうかを調べるには、indexOfを䜿甚するこずもできたす。 レギュラヌを䜿甚するず、さらに進んでより耇雑なパタヌンを䜜成できたす。



任意の数を芋぀ける必芁があるずしたす。 レギュラヌシヌズンに文字セットを角かっこに入れるず、これは匏のこの郚分が角かっこ内の文字のいずれかに䞀臎するこずを意味したす。



䞡方の匏は、数字を含む行にありたす。



 console.log(/[0123456789]/.test("in 1992")); // → true console.log(/[0-9]/.test("in 1992")); // → true
      
      







角括匧内では、2文字間のダッシュを䜿甚しお、Unicodeでシヌケンスが指定されおいる文字の範囲を指定したす。 0から9の文字が䞀列に䞊んでいる48から57のコヌドため、[0-9]はすべおをキャプチャし、任意の数字ず䞀臎したす。



文字のいく぀かのグルヌプには、独自の組み蟌み略語がありたす。



\ d任意の数字

\ w英数字

\ s空癜スペヌス、タブ、改行など

\ Dは数字ではありたせん

\ Wは英数字ではありたせん

\ Sは空癜ではありたせん

。 改行以倖の任意の文字



したがっお、次の匏を䜿甚しお、2003-01-01 15:20のような日付ず時刻の圢匏を蚭定できたす。



 var dateTime = /\d\d-\d\d-\d\d\d\d \d\d:\d\d/; console.log(dateTime.test("30-01-2003 15:20")); // → true console.log(dateTime.test("30-jan-2003 15:20")); // → false
      
      







ひどいですね。 バックスラッシュが倚すぎるず、パタヌンの理解が困難になりたす。 埌で少し改善したす。



バックスラッシュは角括匧でも䜿甚できたす。 たずえば、[\ d。]は数字たたはピリオドを意味したす。 角括匧内のドットは特別な意味を倱い、単なるドットに倉わるこずに泚意しおください。 +など、他の特殊文字に぀いおも同じこずが蚀えたす。



文字セットを反転するこずができたす-぀たり、セット内の文字以倖の文字を芋぀ける必芁があるずいうこずです-開始角括匧の盎埌に^蚘号を眮くこずによっお。



 var notBinary = /[^01]/; console.log(notBinary.test("1100100010100110")); // → false console.log(notBinary.test("1100100010200110")); // → true
      
      







テンプレヌトの䞀郚を繰り返したす



1぀の番号を芋぀ける方法を知っおいたす。 そしお、敎数を芋぀ける必芁がある堎合-1桁以䞊の数字のシヌケンス



レギュラヌシヌズンで䜕かの埌に+蚘号を付けるず、この芁玠を耇数回繰り返すこずができたす。 / \ d + /は、1桁以䞊の数字を意味したす。



 console.log(/'\d+'/.test("'123'")); // → true console.log(/'\d+'/.test("''")); // → false console.log(/'\d*'/.test("'123'")); // → true console.log(/'\d*'/.test("''")); // → true
      
      







アスタリスク*の倀はほが同じですが、パタヌンをれロ回衚瀺できたす。 䜕かの埌にアスタリスクが付いおいる堎合、その行にテンプレヌトが存圚するこずを劚げるこずはありたせん。れロ回だけ存圚したす。



疑問笊は、テンプレヌトの䞀郚をオプションにしたす。぀たり、れロたたは1回出珟したす。 次の䟋では、u蚘号が発生する堎合がありたすが、パタヌンは存圚しない堎合にも䞀臎したす。



 var neighbor = /neighbou?r/; console.log(neighbor.test("neighbour")); // → true console.log(neighbor.test("neighbor")); // → true
      
      







パタヌンが発生する正確な回数を指定するには、䞭括匧を䜿甚したす。 芁玠の埌の{4}は、行に4回出珟する必芁があるこずを意味したす。 間隔を蚭定するこずもできたす。{2,4}は、芁玠が2回以䞊4回以䞋を満たす必芁があるこずを意味したす。



1桁たたは2桁の日、月、および時間を蚱可する別のバヌゞョンの日時圢匏。 そしお圌女はもう少し読みやすいです。



 var dateTime = /\d{1,2}-\d{1,2}-\d{4} \d{1,2}:\d{2}/; console.log(dateTime.test("30-1-2003 8:45")); // → true
      
      







数倀の1぀を省略するこずにより、オヌプン゚ンドギャップを䜿甚できたす。 {、5}は、パタヌンが0〜5回発生するこずを意味し、{5、}-5回以䞊発生するこずを意味したす。



郚分匏のグルヌプ化



耇数の芁玠で*たたは+挔算子を䞀床に䜿甚するには、括匧を䜿甚できたす。 括匧で囲たれた芏則性の郚分は、挔算子の芳点から1぀の芁玠ず芋なされたす。



 var cartoonCrying = /boo+(hoo+)+/i; console.log(cartoonCrying.test("Boohoooohoohooo")); // → true
      
      







最初ず2番目のプラスは、booずhooの2番目の文字oにのみ適甚されたす。 3番目の+はグルヌプ党䜓に属しhoo +、これらのシヌケンスの1぀以䞊を芋぀けたす。



匏の最埌にある文字iは、通垞の倧文字ず小文字を区別しないため、Bはbず䞀臎したす。



マッチずグルヌプ



テスト方法は、定期的にチェックする最も簡単な方法です。 䞀臎が芋぀かったかどうかのみを報告したす。 レギュラヌにはexecメ゜ッドもありたす。䜕も芋぀からなかった堎合はnullを返したす。それ以倖の堎合は、䞀臎に関する情報を含むオブゞェクトを返したす。



 var match = /\d+/.exec("one two 100"); console.log(match); // → ["100"] console.log(match.index); // → 8
      
      







返されるexecオブゞェクトには、䞀臎が発生した文字の番号を含むむンデックスプロパティがありたす。 䞀般に、オブゞェクトは文字列の配列のように芋えたす。最初の芁玠は、䞀臎をチェックした文字列です。 この䟋では、これは探しおいた䞀連の数字になりたす。



文字列には、ほが同じ方法で機胜する䞀臎メ゜ッドがありたす。



 console.log("one two 100".match(/\d+/)); // → ["100"]
      
      







括匧でグルヌプ化された郚分匏が正芏衚珟に含たれおいる堎合、これらのグルヌプに䞀臎するテキストも配列に衚瀺されたす。 最初の芁玠は垞に完党に䞀臎したす。 2番目は、最初のグルヌプかっこが他の党員よりも先に出䌚ったグルヌプ、次に2番目のグルヌプなどず䞀臎した郚分です。



 var quotedText = /'([^']*)'/; console.log(quotedText.exec("she said 'hello'")); // → ["'hello'", "hello"]
      
      







グルヌプがたったく芋぀からない堎合たずえば、埌ろに疑問笊がある堎合、配列内のその䜍眮にはundefinedが含たれたす。 グルヌプが耇数回䞀臎する堎合、最埌の䞀臎のみが配列に含たれたす。



 console.log(/bad(ly)?/.exec("bad")); // → ["bad", undefined] console.log(/(\d)+/.exec("123")); // → ["123", "3"]
      
      







グルヌプは、文字列の䞀郚を抜出するのに圹立ちたす。 文字列に日付があるかどうかを確認するだけでなく、抜出しおオブゞェクトを衚す日付を䜜成する必芁がある堎合は、数字のシヌケンスを括匧で囲み、execの結果から日付を遞択できたす。



しかし、手始めに、JavaScriptで日付ず時刻を保存する奜たしい方法を孊ぶ小さな䜙談。



日付タむプ



JavaScriptには、日付甚の暙準オブゞェクトタむプがありたす。 日付ず呌ばれたす。 newを介しお日付オブゞェクトを䜜成するだけの堎合、珟圚の日付ずレミヌを取埗したす。



 console.log(new Date()); // → Sun Nov 09 2014 00:07:57 GMT+0300 (CET)
      
      







特定の時間を含むオブゞェクトを䜜成するこずもできたす。



 console.log(new Date(2015, 9, 21)); // → Wed Oct 21 2015 00:00:00 GMT+0300 (CET) console.log(new Date(2009, 11, 9, 12, 59, 59, 999)); // → Wed Dec 09 2009 12:59:59 GMT+0300 (CET)
      
      







JavaScriptは、月番号がれロから始たり、日番号が1から始たるずいう芏則を䜿甚したす。 これはばかげおばかげおいたす。 気を぀けお。



最埌の4぀の匕数時間、分、秒、ミリ秒はオプションであり、れロに等しくない堎合。



タむムスタンプは、1970幎の初めから経過したミリ秒数ずしお保存されたす。 負の数倀は1970幎たで䜿甚されたすこれは、その頃に䜜成されたUnixの時間契玄によるものです。 日付オブゞェクトのgetTimeメ゜ッドは、この数倀を返したす。 自然に倧きいです。

 console.log(new Date(2013, 11, 19).getTime()); // → 1387407600000 console.log(new Date(1387407600000)); // → Thu Dec 19 2013 00:00:00 GMT+0100 (CET)
      
      







Dateコンストラクタヌに1぀の匕数を指定するず、ミリ秒数ずしお扱われたす。 Dateオブゞェクトを䜜成しおgetTimeメ゜ッドを呌び出すか、Date.now関数を呌び出すこずにより、ミリ秒の珟圚の倀を取埗できたす。



Dateオブゞェクトには、コンポヌネントを取埗するためのgetFullYear、getMonth、getDate、getHours、getMinutes、およびgetSecondsメ゜ッドがありたす。 たた、93や14など、かなり圹に立たない2桁のコヌドを返すgetYearメ゜ッドもありたす。



テンプレヌトの必芁な郚分を括匧で囲んだので、文字列から盎接日付オブゞェクトを䜜成できたす。



 function findDate(string) { var dateTime = /(\d{1,2})-(\d{1,2})-(\d{4})/; var match = dateTime.exec(string); return new Date(Number(match[3]), Number(match[2]) - 1, Number(match[1])); } console.log(findDate("30-1-2003")); // → Thu Jan 30 2003 00:00:00 GMT+0100 (CET)
      
      







単語ず行の境界線



残念ながら、findDateは文字列「100-1-30000」から無意味な日付00-1-3000も喜んで取埗したす。 䞀臎は行のどこでも発生する可胜性があるため、この堎合は2番目の文字で始たり、最埌から2番目の文字で終了したす。



文字列党䜓を取埗するために䞀臎を匷制する必芁がある堎合は、^および$ラベルを䜿甚したす。 ^は行の先頭に䞀臎し、$は末尟に䞀臎したす。 したがっお、/ ^ \ d + $ /は1桁たたは耇数の数字のみで構成される行に䞀臎し、/ ^/感嘆笊で始たる行に䞀臎し、/ x ^ /はどの行にも䞀臎したせん行の先頭より前にx。



䞀方、日付が単語の境界で開始および終了するこずを確認する必芁がある堎合は、\ bラベルを䜿甚したす。 単語の境界は、行の先頭たたは末尟、たたは英数字\ wが䞀方の偎にあり、もう䞀方の偎に英数字ではない行の任意の堎所になりたす。



 console.log(/cat/.test("concatenate")); // → true console.log(/\bcat\b/.test("concatenate")); // → false
      
      







境界ラベルはシンボルではないこずに泚意しおください。 これは単なる制限であり、特定の条件が満たされた堎合にのみ䞀臎するこずを意味したす。



遞択テンプレヌト



テキストに数字だけでなく、数字の埌に単数圢たたは耇数圢の豚、牛、たたは鶏が続くかどうかを調べる必芁があるずしたす。



3぀の垞連を曞いお順番にチェックするこずもできたすが、もっず良い方法がありたす。 シンボル| テンプレヌトの巊偎ず右偎の遞択肢を瀺したす。 そしお、私たちは次のように蚀うこずができたす



 var animalCount = /\b\d+ (pig|cow|chicken)s?\b/; console.log(animalCount.test("15 pigs")); // → true console.log(animalCount.test("15 pigchickens")); // → false
      
      







括匧は、|が適甚されるパタヌンの郚分を制限したす。これらの挔算子の倚くを次々に配眮しお、3぀以䞊のオプションの遞択を瀺すこずができたす。



怜玢゚ンゞン



正芏衚珟はフロヌチャヌトず考えるこずができたす。 次の図は、最新の家畜の䟋を瀺しおいたす。







図の巊偎から右偎ぞのパスが芋぀かった堎合、匏は文字列ず䞀臎したす。 行内の珟圚の䜍眮を蚘憶し、四角圢を通過するたびに、その䜍眮の盎埌の行の郚分が四角圢の内容ず䞀臎するこずを確認したす。



そのため、フロヌチャヌトを通過するずきに「3぀の豚」の行で定期的に䞀臎するものを確認するこずは次のようになりたす。



-䜍眮4には単語の境界があり、最初の長方圢を枡したす

-4番目の䜍眮から数を芋぀け、2番目の長方圢を通過したす

-䜍眮5で、1぀のパスは2番目の長方圢の前で閉じ、2番目のパスはさらにスペヌスを空けお長方圢に進みたす。 数字ではなくスペヌスがあり、2番目の方法を遞択したす。

-今、私たちは䜍眮6にあり、「豚」の始たりであり、パスの䞉重分岐にありたす。 行に「牛」や「鶏」はありたせんが、「豚」は存圚するため、このパスを遞択したす。

-䞉重分岐埌の䜍眮9で、1぀のパスが「s」の呚りを回り、単語境界を持぀最埌の長方圢に進み、2番目のパスが「s」を通りたす。 「s」があるので、そこに行きたす。

-䜍眮10では、行の終わりにあり、単語の境界のみが䞀臎したす。 行の終わりは境界ず芋なされ、最埌の長方圢を通過したす。 そしお、テンプレヌトを芋぀けたした。



基本的に、正芏衚珟は次のように機胜したす。アルゎリズムは行の先頭から開始され、そこで䞀臎するものを芋぀けようずしたす。 私たちの堎合、そこには単語の境界があるので、最初の長方圢を通過したす-しかし、そこには数字がありたせんので、2番目の長方圢で぀たずきたす。 次に、圌は行の2番目の文字に移動し、そこで䞀臎するものを芋぀けようずしたす...など、䞀臎するものが芋぀かるか、行の終わりに達するたで続きたす。



キックバック



芏則性/ \ b[01] + b | \ d + | [\ da-f] h\ b /は、bが埌に続く2進数、サフィックスのない10進数、たたは16進数0〜 9たたは文字a〜hの埌にhが続きたす。 察応するチャヌト







䞀臎の怜玢では、文字列にそのような番号がない堎合でも、アルゎリズムが䞊䜍パス2進数に沿っお進むこずがありたす。 たずえば、「103」ずいう行がある堎合、番号3に到達しお初めおア​​ルゎリズムが間違ったパス䞊にあるこずを理解するこずは明らかです。 䞀般に、ラむンはレギュラヌシヌズンず䞀臎したすが、このブランチではありたせん。



その埌、アルゎリズムはロヌルバックしたす。 分岐点で、圌は珟圚の䜍眮を蚘憶したすこの堎合、これは単語境界の盎埌の行の先頭です。遞択したパスが機胜しない堎合は、戻っお別のパスを詊すこずができたす。 行「103」の堎合、トリプルに出䌚った埌、圌は戻り、10進数の方法を詊みたす。 これは機胜するため、䞀臎するものが芋぀かりたす。



アルゎリズムは、完党に䞀臎するものが芋぀かるずすぐに停止したす。 これは、耇数のオプションが衚瀺される堎合でも、そのうちの1぀だけがレギュラヌシヌズンで衚瀺される順序で䜿甚されるこずを意味したす。



+や*などの繰り返し挔算子を䜿甚するず、キックバックが発生したす。 文字列「abcxe」で/^.*x/を探すず、芏則性の䞀郚*行党䜓を吞収しようずしたす。 アルゎリズムは、「x」も必芁であるこずを認識したす。 行の終わりの埌に「x」がないため、アルゎリズムは1文字をロヌルバックしお䞀臎を芋぀けようずしたす。 abcxの埌、xも存圚しないため、サブストリングabcにすでにロヌルバックされたす。 そしお、行の埌、圌はxを芋぀け、䜍眮0から4で成功したマッチに぀いお報告したす。



耇数のロヌルバックに぀ながる定期的なシヌズンを曞くこずができたす。 この問題は、パタヌンがさたざたな方法で入力ず䞀臎する堎合に発生したす。 たずえば、2進数の正芏衚珟を曞くずきに間違えた堎合、誀っお/[01] ++ b /のようなものを曞く可胜性がありたす。







アルゎリズムが、末尟に「b」を含たないれロず1の長い文字列でそのようなパタヌンを怜玢する堎合、最初に数倀がなくなるたで内郚ルヌプを通過したす。 その埌、圌は最埌に「b」がないこずに気づくでしょう、圌は1぀の䜍眮をロヌルバックし、倖偎のルヌプを通過し、再びあきらめ、内偎のルヌプに沿っおもう1぀の䜍眮をロヌルバックしようずしたす...そしお圌は䞡方のルヌプを䜿甚しおこの方法で怜玢を続けたす ぀たり、文字列の各文字の凊理量は2倍になりたす。 数十人のキャラクタヌでさえ、マッチを芋぀けるのに非垞に長い時間がかかりたす。



眮換方法



行には、文字列の䞀郚を別の文字列で眮換できるreplaceメ゜ッドがありたす。



 console.log("".replace("", "")); // → 
      
      







最初の匕数は芏則的である堎合がありたす。この堎合、文字列内の最初の正芏衚珟が眮き換えられたす。 「g」グロヌバル、ナニバヌサルオプションをレギュラヌに远加するず、最初のオカレンスだけでなく、すべおのオカレンスが眮き換えられたす



 console.log("Borobudur".replace(/[ou]/, "a")); // → Barobudur console.log("Borobudur".replace(/[ou]/g, "a")); // → Barabadar
      
      







「すべお眮換」オプションを別の匕数たたはreplaceAll型の別のメ゜ッドに枡すこずは理にかなっおいたす。 しかし、残念ながら、オプションはレギュラヌシヌズン自䜓を通過したす。



レギュラヌシヌズンの指定された行にあるグルヌプぞのリンクを䜿甚するず、レギュラヌのすべおのパワヌが明らかになりたす。 たずえば、「姓、名」の圢匏で、人の名前を1行に1぀ず぀含む行がありたす。 それらを亀換しおコンマを削陀しお「姓」を取埗する必芁がある堎合は、次のように蚘述したす。



 console.log( "Hopper, Grace\nMcCarthy, John\nRitchie, Dennis" .replace(/([\w ]+), ([\w ]+)/g, "$2 $1")); // → Grace Hopper // John McCarthy // Dennis Ritchie
      
      







眮換行の$ 1および$ 2は、括匧で囲たれた文字のグルヌプを指したす。 $ 1は最初のグルヌプに䞀臎するテキストに、$ 2は2番目のグルヌプに、以䞋同様に、最倧$ 9に眮換されたす。 䞀臎党䜓が$倉数に含たれおいたす。



関数を2番目の匕数ずしお枡すこずもできたす。 眮換ごずに、関数が呌び出され、その匕数が芋぀かったグルヌプおよび文字列党䜓に䞀臎する郚分になり、その結果が新しい行に挿入されたす。



簡単な䟋



 var s = "the cia and fbi"; console.log(s.replace(/\b(fbi|cia)\b/g, function(str) { return str.toUpperCase(); })); // → the CIA and FBI
      
      







そしお、ここにもっず面癜いものがありたす



 var stock = "1 lemon, 2 cabbages, and 101 eggs"; function minusOne(match, amount, unit) { amount = Number(amount) - 1; if (amount == 1) //   ,  's'   unit = unit.slice(0, unit.length - 1); else if (amount == 0) amount = "no"; return amount + " " + unit; } console.log(stock.replace(/(\d+) (\w+)/g, minusOne)); // → no lemon, 1 cabbage, and 100 eggs
      
      







コヌドは文字列を受け取り、数字の埌に出珟するすべおの単語を怜玢し、各数字が1぀ず぀枛った文字列を返したす。



グルヌプ\ d +は匕数量に分類され、\ w +は単䜍に分類されたす。 この関数は量を数倀に倉換したす。テンプレヌトは\ d +であるため、これは垞に機胜したす。 そしお、圌は単語が1人しか残っおいない堎合に倉曎したす。



欲



replaceを䜿甚するず、JavaScriptコヌドからすべおのコメントを削陀する関数を簡単に䜜成できたす。 これが最初の詊みです。



 function stripComments(code) { return code.replace(/\/\/.*|\/\*[^]*\*\//g, ""); } console.log(stripComments("1 + /* 2 */3")); // → 1 + 3 console.log(stripComments("x = 10;// ten!")); // → x = 10; console.log(stripComments("1 /* a */+/* b */ 1")); // → 1 1
      
      







「or」挔算子の前の郚分は、2぀のスラッシュずそれに続く改行文字以倖の任意の数の文字に䞀臎したす。 耇数行のコメントを削陀する郚分はより耇雑です。 [^]、぀たり任意の文字を芋぀ける方法ずしおの空でない文字。ブロックコメントは新しい行で継続され、改行は期間ず䞀臎しないため、ピリオドを䜿甚できたせん。



しかし、前の䟋の結論は間違っおいたす。なんで



[^] *郚分は、最初にできるだけ倚くの文字をキャプチャしようずしたす。このため、レギュラヌシヌズンの次の郚分で䞀臎が芋぀からない堎合、1぀のキャラクタヌがロヌルバックされ、再詊行されたす。この䟋では、アルゎリズムは文字列党䜓をキャプチャしようずし、その埌ロヌルバックしたす。 4文字をロヌルバックするず、圌は行に* /-を芋぀けたすが、これは私たちが達成したものではありたせん。コメントを1぀だけキャプチャし、行の最埌に移動しお最埌のコメントを芋぀けたくはありたせんでした。



このため、繰り返し挔算子+、*、、および{}は貪欲であるず蚀いたす。぀たり、最初にできるだけ倚くを取埗し、次に戻りたす。そのような挔算子+、*、??、{}の埌に質問を眮くず、それらは欲匵りでないものに倉わり、可胜な限り小さな出珟を芋぀け始めたす。



そしお、それが私たちに必芁なものです。アスタリスクに可胜な最小数の行文字で䞀臎を怜出させるこずにより、1ブロックのコメントのみを吞収し、それ以䞊は吞収したせん。



 function stripComments(code) { return code.replace(/\/\/.*|\/\*[^]*?\*\//g, ""); } console.log(stripComments("1 /* a */+/* b */ 1")); // → 1 + 1
      
      







貪欲でない挔算子の代わりに貪欲な挔算子を䜿甚するず、倚くの゚ラヌが発生したす。再生挔算子を䜿甚するずきは、垞に貪欲でないオプションを最初に考慮しおください。



RegExpオブゞェクトの動的䜜成



堎合によっおは、コヌドの蚘述時点で正確なパタヌンがわからないこずがありたす。たずえば、テキストでナヌザヌ名を怜玢し、アンダヌスコアで囲む必芁がありたす。プログラムの開始埌に名前を認識するだけなので、スラッシュ゚ントリは䜿甚できたせん。



ただし、文字列を䜜成しおRegExpコンストラクタヌを䜿甚するこずはできたす。以䞋に䟋を瀺したす。



 var name = ""; var text = "     ."; var regexp = new RegExp("\\b(" + name + ")\\b", "gi"); console.log(text.replace(regexp, "_$1_")); // →   __   .
      
      







単語の境界を䜜成するずきは、スラッシュを䜿甚した通垞の行ではなく通垞の行に曞き蟌むため、二重スラッシュを䜿甚する必芁がありたす。RegExpの2番目の匕数には、レギュラヌのオプションが含たれたす。この䟋では、「gi」、぀たり グロヌバルで倧文字ず小文字を区別したせん。



しかし、名前が「dea + hl [] rd」の堎合ナヌザヌがカルハッカヌの堎合はどうでしょうか。その結果、文字列に䞀臎するものが芋぀からない無意味なレギュラヌシヌズンが埗られたす。



嫌いな文字の前にバックスラッシュを远加できたす。\ bたたは\ nは特殊文字であるため、文字の前にバックスラッシュを远加するこずはできたせん。ただし、英数字以倖の文字の前に問題なくスラッシュを远加できたす。



 var name = "dea+hl[]rd"; var text = " dea+hl[]rd  ."; var escaped = name.replace(/[^\w\s]/g, "\\$&"); var regexp = new RegExp("\\b(" + escaped + ")\\b", "gi"); console.log(text.replace(regexp, "_$1_")); // →  _dea+hl[]rd_  .
      
      







怜玢方法



indexOfメ゜ッドはレギュラヌでは䜿甚できたせん。しかし、芏則性を期埅するだけの怜玢方法がありたす。indexOfず同様に、最初の発生のむンデックスを返したす。発生しなかった堎合は-1を返したす。



 console.log(" word".search(/\S/)); // → 2 console.log(" ".search(/\S/)); // → -1
      
      







残念ながら、特定のオフセットで始たる䞀臎を怜玢するようにメ゜ッドを蚭定するこずは䞍可胜ですindexOfでこれを行う方法。それは圹立぀でしょう。



LastIndexプロパティ



execメ゜ッドは、文字列内の指定された䜍眮から怜玢を開始する䟿利な方法も提䟛したせん。しかし、䞍䟿な方法がありたす。



通垞のオブゞェクトにはプロパティがありたす。それらの1぀は、文字列を含む゜ヌスです。もう1぀はlastIndexで、特定の条件で、゚ントリの次の怜玢を開始する堎所を制埡したす。



これらの条件には、グロヌバルオプションgの存圚の必芁性、およびexecメ゜ッドを䜿甚しお怜玢を実行する必芁があるずいう事実が含たれたす。より合理的な解決策は、単に远加の匕数をexecに枡すこずを蚱可するこずですが、合理性はJavaScriptの通垞のむンタヌフェヌスの基本的な機胜ではありたせん。



 var pattern = /y/g; pattern.lastIndex = 3; var match = pattern.exec("xyzzy"); console.log(match.index); // → 4 console.log(pattern.lastIndex); // → 5
      
      







怜玢が成功した堎合、execの呌び出しは、芋぀かった゚ントリの埌の䜍眮を指すようにlastIndexプロパティを曎新したす。成功しなかった堎合、lastIndexはれロに蚭定されたす-新しく䜜成されたオブゞェクトのlastIndexのように。



グロヌバルな通垞倉数ずいく぀かのexec呌び出しを䜿甚する堎合、lastIndexに察するこれらの自動曎新は問題を匕き起こす可胜性がありたす。垞連は、前回の通話で残った䜍眮から怜玢を開始できたす。



 var digit = /\d/g; console.log(digit.exec("here it is: 1")); // → ["1"] console.log(digit.exec("and now: 1")); // → null
      
      







gオプションのもう1぀の興味深い効果は、matchメ゜ッドの動䜜方法が倉わるこずです。このオプションで呌び出されるず、execの結果に類䌌した配列を返す代わりに、文字列内のすべおのテンプレヌトの出珟を怜出し、芋぀かった郚分文字列の配列を返したす。



 console.log("".match(//g)); // → ["", ""]
      
      







したがっお、グロヌバル正芏倉数には泚意しおください。それらが必芁な堎合-眮き換えの呌び出したたはlastIndexを特に䜿甚する堎所-おそらくそれらが適甚されるべきすべおの堎合。



発生サむクル





兞型的なタスクは、lastIndexずexecを䜿甚しお、ルヌプの本文内の䞀臎オブゞェクトにアクセスできるように、文字列内のすべおのテンプレヌトの出珟を調べるこずです。



 var input = "  3   ... 42  88."; var number = /\b(\d+)\b/g; var match; while (match = number.exec(input)) console.log(" ", match[1], "  ", match.index); // →  3  14 //  42  33 //  88  40
      
      







割り圓お倀が割り圓おられた倀であるずいう事実が䜿甚されたす。whileルヌプの条件ずしおmatch = re.execinput構文を䜿甚しお、各反埩の開始時に怜玢し、結果を倉数に保存し、すべおの䞀臎が芋぀かったらルヌプを終了したす。



INIファむルの解析





この章の終わりに、正芏衚珟を䜿甚した問題を怜蚎したす。自動モヌドでむンタヌネットを介しお敵に関する情報を収集するプログラムを䜜成しおいるず想像しおください。 プログラム党䜓ではなく、蚭定ファむルを読み取る郚分のみを蚘述したす。申し蚳ありたせん。ファむルは次のようになりたす。



 searchengine=http://www.google.com/search?q=$1 spitefulness=9.7 ;       ;       [larry] fullname=Larry Doe type=   website=http://www.geocities.com/CapeCanaveral/11451 [gargamel] fullname=Gargamel type=  outputdir=/home/marijn/enemies/gargamel
      
      







正確なファむル圢匏非垞に広く䜿甚されおおり、通垞INIず呌ばれたすは次のずおりです。-



空癜行ずセミコロンで始たる行は無芖されたす

-角括匧で囲たれた行は新しいセクションを開始したす

-英数字識別子を含む行=が続き、このセクションに蚭定を远加したす。



それ以倖はすべお䞍正なデヌタです。



私たちのタスクは、このような文字列をオブゞェクトの配列に倉換するこずです。各オブゞェクトは、名前プロパティず蚭定の配列を持ちたす。各セクションには、1぀のオブゞェクトず、ファむルの䞊郚にあるグロヌバル蚭定甚のもう1぀のオブゞェクトが必芁です。



行ごずにファむルを解析する必芁があるため、ファむルを行に分割するこずから始めるこずをお勧めしたす。このため、第6章ではstring.split "\ n"を䜿甚したした。 OSによっおは、行を倉換するために1぀の文字ではなく\ rを䜿甚したす。 splitメ゜ッドは匕数ずしお正芏衚珟を受け入れるため、匏/ \ r\ N /を䜿甚しお行を分割できたす。これにより、行間で単䞀の\ nおよび\ r \ nが蚱可されたす。



 function parseINI(string) { //   ,     var currentSection = {name: null, fields: []}; var categories = [currentSection]; string.split(/\r?\n/).forEach(function(line) { var match; if (/^\s*(;.*)?$/.test(line)) { return; } else if (match = line.match(/^\[(.*)\]$/)) { currentSection = {name: match[1], fields: []}; categories.push(currentSection); } else if (match = line.match(/^(\w+)=(.*)$/)) { currentSection.fields.push({name: match[1], value: match[2]}); } else { throw new Error(" '" + line + "'   ."); } }); return categories; }
      
      







コヌドはすべおの行を調べ、珟圚のセクション「珟圚のセクション」のオブゞェクトを曎新したす。最初に、/ ^ \ s *;。*$ /芏則を䜿甚しお、行を無芖できるかどうかをチェックしたす。どのように機胜するのでしょうかカッコ内の郚分はコメントず䞀臎したすか芏則性をスペヌスのみで構成される行ず䞀臎させたす。



行がコメントでない堎合、コヌドは新しいセクションを開始するかどうかを確認したす。その堎合、珟圚のセクションの新しいオブゞェクトが䜜成され、それに埌続の蚭定が远加されたす。



最埌の有意矩な機䌚-文字列は通垞の蚭定です。この堎合、珟圚のオブゞェクトに远加されたす。



オプションが機胜しない堎合、関数ぱラヌをスロヌしたす。



^ず$を頻繁に䜿甚するず、匏が郚分ではなく文字列党䜓ず䞀臎するこずに泚意しおください。これらを䜿甚しない堎合、コヌド党䜓は機胜したすが、時々奇劙な結果が生成され、そのような゚ラヌを远跡するこずは困難です。



ifmatch = string.match...コンストラクトは、whileルヌプの条件ずしお割り圓おを䜿甚するトリックに䌌おいたす。倚くの堎合、䞀臎呌び出しが成功するこずを知らないため、これをチェックするifブロック内の結果オブゞェクトにのみアクセスできたす。ifチェックの矎しい連鎖を壊さないために、怜玢結果を倉数に割り圓お、この割り圓おをすぐにチェックずしお䜿甚したす。



囜際文字



蚀語の最初の単玔な実装ず、そのような実装の「花厗岩」でのその埌の固定のために、JavaScriptレギュラヌは英語では芋぀からない文字で鈍いです。たずえば、JavaScript正芏衚珟の「文字」蚘号は、英語のアルファベットの26文字の1぀であり、䜕らかの理由で䞋線が匕かれおいる堎合がありたす。䞀意の文字であるタむプéたたはβの文字は、\ wず䞀臎したせんおよび\ Wず䞀臎したす぀たり、非文字ず䞀臎したす。



奇劙な偶然の䞀臎により、\ sスペヌスは、歎史的に、Unicodeでスペヌス文字ず芋なされるすべおの文字ず䞀臎したした。



他の蚀語の䞀郚の正則化実装には、「すべお倧文字」、「すべおの句読点」、「制埡文字」など、Unicode文字の特別なカテゎリを怜玢するための特別な構文がありたす。このようなカテゎリをJavaScriptに远加する蚈画がありたすが、おそらくすぐには実装されたせん。



たずめ





レギュラヌは、ストリング内の怜玢パタヌンを衚すオブゞェクトです。構文を䜿甚しおこれらのパタヌンを衚珟したす。



/ abc /文字のシヌケンス

/ [abc] /リストからの任意の文字

/ [^ abc] /リストからの文字を陀く任意の文字

/ [0-9] /範囲内の任意の文字

/ x + /パタヌンの1回以䞊の出珟x

/ x + / 1぀以䞊の出珟、貪欲でない

/ x * / 0回以䞊の出珟

/ x/ 0回たたは1回の出珟

/ x {2,4} / 2〜4回の出珟

/abc/グルヌプ

/ a | b | c /任意耇数のパタヌンから

/ \ d /任意の数字

/ \ w /任意の英数字「文字」

/ \ s /任意の空癜

/./改行以倖の任意の文字

/ \ b /単語の境界

/ ^ /行の開始

/ $ /行



の終わり通垞の行には、行にパタヌンがあるかどうかを確認するテストメ゜ッドがありたす。芋぀かったすべおのグルヌプを含む配列を返すexecメ゜ッドがありたす。配列には、䞀臎が発生した文字の番号を含むむンデックスプロパティがありたす。



文字列には、パタヌンを怜玢するための䞀臎メ゜ッドず、オカレンスの開始䜍眮のみを返す怜玢メ゜ッドがありたす。 replaceメ゜ッドは、パタヌンの出珟を別の文字列に眮き換えるこずができたす。さらに、テンプレヌトおよび芋぀かったグルヌプに基づいお眮換文字列を䜜成する関数を眮換するために枡すこずができたす。



レギュラヌには、スラッシュの埌に曞き蟌む蚭定がありたす。オプションiは芏則性の倧文字ず小文字を区別せず、オプションgはそれをグロヌバルにしたす。これにより、replaceメ゜ッドは、最初の゚ントリだけでなく、芋぀かったすべおの゚ントリを匷制的に眮換したす。



RegExpコンストラクタヌを䜿甚しお、文字列から正芏衚珟を䜜成できたす。



レギュラヌは、䞍快なハンドルを持぀鋭い道具です。䞀郚のタスクを倧幅に簡玠化し、他の耇雑なタスクを解決するずきに管理䞍胜になる可胜性がありたす。垞連を䜿甚する胜力の䞀郚は、圌らが意図しおいないタスクを詰め蟌む誘惑に抵抗できるようにするこずです。



挔習



必然的に、問題を解決する際に、理解できないケヌスが発生し、時には絶望し、䞀郚の垞連の予枬できない動䜜を芋るこずがありたす。debuggex.comのようなオンラむンサヌビスを䜿甚しおレギュラヌシヌズンの振る舞いを調査するず、芖芚化を確認しお目的の効果ず比范できるこずがありたす。



レギュラヌゎルフ


コヌド内の「ゎルフ」は、特定のプログラムを最小限のキャラクタヌで衚珟する必芁があるゲヌムです。レギュラヌゎルフは、特定のパタヌンを怜玢するために、可胜な限り小さいレギュラヌを曞くための実甚的な緎習であり、そのパタヌンのみです。



各調敎に぀いお、通垞の行を䜜成しお、それらが行にあるかどうかを確認したす。レギュラヌは、これらの指定された郚分文字列のみを芋぀ける必芁がありたす。特に断りのない限り、単語の境界に぀いお心配しないでください。正垞に動䜜するようになったら、それを枛らしおみおください。



-車ず猫

-ポップずプロップ

-フェレット、フェリヌ、およびフェラヌリ-iousで

終わる単語

-ピリオド、コンマ、コロンたたはセミコロンが続くスペヌス。

-6文字より長い単語

-文字eのない単語



 //    verify(/.../, ["my car", "bad cats"], ["camper", "high art"]); verify(/.../, ["pop culture", "mad props"], ["plop"]); verify(/.../, ["ferret", "ferry", "ferrari"], ["ferrum", "transfer A"]); verify(/.../, ["how delicious", "spacious room"], ["ruinous", "consciousness"]); verify(/.../, ["bad punctuation ."], ["escape the dot"]); verify(/.../, ["hottentottententen"], ["no", "hotten totten tenten"]); verify(/.../, ["red platypus", "wobbling nest"], ["earth bed", "learning ape"]); function verify(regexp, yes, no) { // Ignore unfinished exercises if (regexp.source == "...") return; yes.forEach(function(s) { if (!regexp.test(s)) console.log("  '" + s + "'"); }); no.forEach(function(s) { if (regexp.test(s)) console.log("  '" + s + "'"); }); }
      
      







テキスト内の匕甚笊


ストヌリヌを曞き、どこでもダむアログを瀺すために䞀重匕甚笊を䜿甚したずしたす。ここで、ダむアログの匕甚笊を二重の匕甚笊に眮き換え、are notなどの単語の省略圢に単䞀の匕甚笊を残したす。



これら2぀の匕甚笊の䜿甚を区別するパタヌンを考え出し、眮換を実行するreplaceメ゜ッドの呌び出しを蚘述したす。



再び数字


数字のシヌケンスは、単玔な芏則的なパタヌン/ \ d + /で芋぀けるこずができたす。



JavaScriptスタむルで蚘述された数字のみを怜玢する匏を蚘述したす。数字の前のマむナスたたはプラスの可胜性、小数点、および5e-3たたは1E10の指数衚蚘をサポヌトする必芁がありたす-ここでもプラスたたはマむナスが可胜です。たた、ポむントの前埌に必ずしも数字があるわけではありたせんが、数字が単䞀のポむントで構成されおいるわけではないこずに泚意しおください。぀たり、.5たたは5は有効な数倀ですが、1぀のポむント自䜓は有効ではありたせん。



 //   . var number = /^...$/; // Tests: ["1", "-1", "+15", "1.55", ".5", "5.", "1.3e2", "1E-4", "1e+12"].forEach(function(s) { if (!number.test(s)) console.log("  '" + s + "'"); }); ["1a", "+-1", "1.2.3", "1+1", "1e4.5", ".5.", "1f5", "."].forEach(function(s) { if (number.test(s)) console.log("  '" + s + "'"); });
      
      






All Articles