Chrome以外の多くのブラウザでは、正規表現の後読みがサポートされていない(2018/06/10現在)ので、その対処法。
正規表現をあまり知らない高校生が考えたものなので、もっといい方法があればご教示ください。
2018/12/25追記
以下の例では,普通にsplitを使って取得したほうがよさそうです.
str.split("/").filter(s => s.startsWith("Saito ")).map(s => s.split(" ")[1]);
や
num.split("*").map(s => s.split("^")[0]);
のように.
ですので,あまり例を参考にされないようにお願いします.また,正規表現を使おうとする前に,既存のメソッド(sliceなど)を使って書けないか,と考えることも大切だと思います.
###肯定後読みの代替
const str = "Saito Tsukasa/Sudo Takashi/Saito Shinji/Takeyama Kozo/Ota Hirohisa";
の中(トレンディエンジェルとジャングルポケット)から、「Saito」という苗字の人の下の名前を配列で受け取りたい!という状況を考えてみましょう。
肯定後読みがサポートされているなら、
const names = str.match(/(?<=Saito )[A-Z][a-z]+/g);
のように書けます。これを肯定後読みを使わずに書くと、
const names = str.match(/Saito [A-Z][a-z]+/g).map(s => s.slice(6));
などとなります。まず、Saito 〇〇
にマッチさせて、その後slice
でSaito
の部分を削る。という方法です。
###否定後読みの代替 その1
次に、先ほどの
const str = "Saito Tsukasa/Sudo Takashi/Saito Shinji/Takeyama Kozo/Ota Hirohisa";
から、苗字が「Saito」以外の人の下の名前を配列で受け取りたい!という状況を考えましょう。
これも、否定後読みがサポートされているなら、
const names = str.match(/(?<!Saito )[A-Z][a-z]+(?! |[a-z])/g);
と書けます。これを否定後読みを使わずに書くと、
const names = str.match(/[A-Z][a-z]+ [A-Z][a-z]+/g)
.filter(s => !s.match(/Saito [A-Z][a-z]+/))
.map(s => s.slice(s.indexOf(' ')+1));
などとなります。長ったらしいですが、
- 全ての名前を配列で受け取る。
- 「Saito」という苗字の人を弾く。
- 下の名前だけを
slice
で取り出す。
という方法です。
###否定後読みの代替 その2
今度は
const num = "2^3^12*3*13^4";
($2^{3^{12}} \times 3 \times 13^4$)から底の数字($2, 3, 13$)だけを取り出したい!という状況を考えましょう。
否定後読みを用いて書くと、
const bases = num.match(/(?<!\^|\d)\d+/g);
となります。否定後読みを使わずに書くと、荒技ですが、
const reverse = s => s.split('').reverse().join('');
const bases = reverse(num).match(/\d+(?!\^|\d)/g)
.map(s => reverse(s)).reverse();
などとなります。何をしたかというと、
- 文字列を
reverse
して、後読みを先読みに変える! - 先読みを使いマッチさせる。
- 配列の中の文字列を
reverse
- 配列自体を
reverse
(任意)
このreverse
を使う方法を用いれば大体代替できますね。(言いたいだけ)