これは私の前の質問のフォローアップです
長さ > の最小限の文字列を見つけたいと思いますN
。これは、単語の境界で始まり、入力の終わりで終わります。
例えば:
N = 5、入力 = "aaa bbb cccc dd" 結果 = "cccc dd"
やってみましたが、ミニマルな部分より\b.{5,}?$
も全体にマッチします。input
何regex
を提案しますか?
これは私の前の質問のフォローアップです
長さ > の最小限の文字列を見つけたいと思いますN
。これは、単語の境界で始まり、入力の終わりで終わります。
例えば:
N = 5、入力 = "aaa bbb cccc dd" 結果 = "cccc dd"
やってみましたが、ミニマルな部分より\b.{5,}?$
も全体にマッチします。input
何regex
を提案しますか?
試合の周りの括弧を忘れただけです。使用する
.*(\b.{5,}?)$
今回の問題は貪欲さではなく、熱意です。正規表現は当然、可能な限り早い一致を見つけようとしますが、最後の一致を見つけるのは難しい場合があります。最も簡単な方法は通常、@Arcadien が示した方法です。使用.*
して文字列全体を飲み込み、次にバックトラッキングを使用してリバウンドで一致を見つけます。
ただし、要件についていくつか質問があります。 \b
単語の先頭または末尾に一致する可能性があるため、(たとえば)N=5
文字列が で終わる"foo1 bar2"
場合、結果は" bar2"
(先頭のスペースに注意してください) になります。単語の終わりから始まる一致が本当に必要ですか、それともスペースを削除するか、の先頭に戻る必要があり"foo1"
ますか? また、すべての単語は完全に単語文字で構成されますか? 単語以外の文字があれば、\b
さらに驚くべき場所で一致する可能性があります。
以下の正規表現では、空白以外の文字の完全なチャンクを意味するように「単語」を再定義しました。は.*
、文字列全体を消費することから始めます。次に、先読み - (?=.{5,})
- 何かを照合しようとする前に、強制的に 5 つの位置をバックトラックします。は\s
単語の先頭から一致を開始するように強制するため、残りの正規表現は 1 つ以上の完全な単語をキャプチャします。
/^.*(?=.{5,})\s(\S+(?:\s+\S+)*$)/
var N = 5;
var regex = "^.*(?=.{" + N + ",})\\s(\\S+(?:\\s+\\S+)*$)";
var match = regex.exec(subject);
var result = (match != null) ? match[1] : "";
この正規表現は、長さが 5 文字未満であるか、空白を含まないものには一致しません。それが問題である場合は、お知らせください。微調整します。
入力を逆にすることができます
.split("").reverse().join("")
そして、前の質問の答えを適用してから、上記と同じ関数で一致を逆にします。
このソリューションでは、パフォーマンスは考慮されていません。
(次の 5 文字以上の任意.{5}
の文字) の代わりに (次の 5 文字の任意の文字) を使用してみてください.{5,}
以下は、regexpal \w*.{5}$
を使用して機能しました(@nhahtdhによって改善されました)。これにより、5 文字が続くすべての単語が取得されます。
結果:
String "AAAA BBBB CCCC DDEEE"
Match: "DDEEE"
String "AAAA BBBB CCCC DD"
Match: "CCCC DD"
String "AAAA BBBB CCCC"
Match: "BBBB CCCC"
String "AAAA"
Match: null