質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.71%

JavaScriptの正規表現で、「一番外側の括弧」で抽出したい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 307

kamekamekame

score 9

実現したいこと

正規表現について知りたいです。宜しくお願い致します。

このようなvalueがあります。
<input type="textarea" value="[いぬ[の] しっぽ] [ねこのしっぽ]いぬ ねこ ">

ここから、下記➀➁の配列を取得することは可能でしょうか?

取得したい配列

➀「一番外側の括弧」という単位で配列
Array [ "いぬ[の] しっぽ", "ねこのしっぽ" ]

➁それ以外の文字列でスペース単位の配列
Array [ "いぬ", "ねこ" ]

注意したい点

・括弧の入れ子の数は不明です。

・括弧は必ずセットになります。(たとえば[いぬ[の]] しっぽ]のように括弧がセットにならないということはありません。)

試したこと

なんとなく大枠の流れはできたのですが、やはり正規表現の部分で躓いています。
下記ですと「一番外側の括弧」ではなく「括弧が出現するたびに」という感じになってしまいます。

どうすればいいか教えて頂けませんでしょうか。

<input type="textarea" value="[いぬ[の] しっぽ] [ねこのしっぽ]いぬ ねこ ">

$('input').on('input', function() {

    // 入力値を取得
    const inputVal = $(this).val();

    // ➀「一番外側の括弧」という単位で配列
    const range = /\[([^\[\] ]+)/g; // ここで「一番外側の括弧」という指定がしたい
    let match;
    let rangeArr = [];
    while ( (match = range.exec(inputVal))!== null ) {
        rangeArr.push(match[1]);
    }
    console.log( 'rangeArr' );
    console.log( rangeArr );

    // ➁それ以外の文字列でスペース単位の配列
    const spaceArr = inputVal.replace(range,'').split(/[\u3000&\x20;]/g);  
    console.log( 'spaceArr' );  
    console.log( spaceArr );  

});
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

正規化された文字列には見えないので、正規表現でやるのは厳しいんじゃないでしょうか……

let blankets = [];
let counter = 0;
let source = "[いぬ[の] しっぽ] [ねこのしっぽ]いぬ ねこ ";

source.split('').forEach(char => {
  if(char === ']') {
    counter--;
  }
  if(char === '[') {
    counter++;
    if(counter === 1) {
      blankets.push('');
      return; // continue
    }
  }
  if(counter > 0) blankets[blankets.length - 1] += char;
});

let temp = source;
blankets.forEach(str => temp = temp.replace(`[${str}]`, ''));
let spaces = temp.trim().split(' ');

console.log(blankets);
// -> (2) ["いぬ[の] しっぽ", "ねこのしっぽ"]
console.log(spaces);
// -> (2) ["いぬ", "ねこ"]

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/17 12:14

    入れ子の数が悩みどころでしたが、カウンターとは!巧いですね。勉強になりました。キモな機能だったのでかなり助かります。どうもありがとうございました!

    キャンセル

0

以下、未検証です。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Regular_Expressions

while (tokenGroup = /([^[]+)|\[([^\]]*)\]/g.exec(string)) {
  const tokenList = tokenGroup.split(' ');
}

質問を誤読していました。
対応する括弧を取得したかったのですね。
https://teratail.com/questions/156083#reply-234347
https://gist.github.com/think49/071350bcc987d82dd836885ea6f5c0d4

Re: kamekamekame さん

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/17 08:52 編集

    ありがとうございます。仰ることがわかっていないせいか、できないようでした。
    ですがリンク先やexecというメソッドについてありがとうございます。引き続き考えてみます。

    キャンセル

  • 2019/06/17 12:49

    すみません。質問を誤読していました。
    履歴から気がついたようですが、同案件の過去回答へのリンクを貼っておきました。

    キャンセル

  • 2019/06/17 13:52

    ありがとうございます。仰るようにあなたのご回答履歴を漁り笑、そちらにあったgithubを使わせて頂きました。
    その後thyda.eiqau様からのご回答もあり、いずれの方法でもできることが確認できまして、その贅沢さにいささか恐縮しております。m(__)m

    ところでお二方のコードですが、正規表現を使っているかどうかの違いで、やっていることは同じですよね。
    いまいちわからないのですが、正規表現を使うことについてはどのようなメリットがあるのでしょうか?

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.71%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る