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

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

ただいまの
回答率

88.80%

正規表現で特定の文字以降を置換する方法について

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 7,176
退会済みユーザー

退会済みユーザー

前提・実現したいこと

対象の文字列に対して、'aaaaa[0]'以降の'[0]'を'[1]'に置換したいのですが、
スマートな正規表現が見つかりません。

ゴリ押しで、対象の文字列の'[0]'を'[1]'に全て置換後、
'aaaaa[1]'を'aaaaa[0]'に戻すことで再現出来るには出来るんですが、
もっとスマートな方法を求めてこちらで質問させて頂きました。

対象文字列の補足

  • 先頭は'aaaaa[0]'で始まり、固定
  • '[bbbbb][0]'や'[ccccc][0]'は最大2セットまで存在し、無いこともある
  • 必ず最後に'[ddddd]'が付く

対象の文字列パターン

// これらの文字列を
'aaaaa[0][ddddd]'
'aaaaa[0][bbbbb][0][ddddd]'
'aaaaa[0][ccccc][0][ddddd]'
'aaaaa[0][bbbbb][0][ccccc][0][ddddd]'

// こんな感じに数字を置換したい
'aaaaa[0][ddddd]'
'aaaaa[0][bbbbb][1][ddddd]'
'aaaaa[0][ccccc][1][ddddd]'
'aaaaa[0][bbbbb][1][ccccc][1][ddddd]'
// 置換対象文字列
var str = 'aaaaa[0][bbbbb][0][ccccc][0][ddddd]';

// 出力したい結果
// こんな感じで'aaaaa[0]'以降の'[0]'を'[1]'へ置換したい
'aaaaa[0][bbbbb][1][ccccc][1][ddddd]'

試したこと

// 置換対象文字列
var str = 'aaaaa[0][bbbbb][0][ccccc][0][ddddd]';

// ゴリ押し方法
str.replace(/\[[0-9]+\]/, '[1]').replace(/aaaaa\[[0-9]+\]/, '[0]');
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

+5

aaaaa[0] を aaaaa[1] に置換するだけなら特別な正規表現は何も要らないと思うのですが…。

  • 一括置換するなら、g フラグを付ける
  • [] をエスケープする

「スマートな正規表現が見つかりません。」とありますが、正規表現の学習のどれほどの時間をかけて、どの程度は理解していますか。

(2017/04/29 20:23追記)

要件を勘違いしていたので、上記アドバイスは忘れてください。
ただ、やりたい要件を書くだけでなく、あなたが「分かっている範囲」と「分からない範囲」を具体化する事も大切だと思います。
どの程度の知識があるのかわからないので、何をアドバイスしていいのか分かりません…。

 String.prototype.replace

とりあえず、下記コードで要件は満たせます。

var str = 'aaaaa[0][bbbbb][0][ccccc][0][ddddd]';
var str2 = str.replace(/(aaaaa\[0\])([\s\S]*\[0\])/, function (string, capture1, capture2) {
  return capture1 + capture2.replace(/\[0(?=\])/g, '[1');
});

console.log(str2);  // "aaaaa[0][bbbbb][1][ccccc][1][ddddd]"

 String.prototype.slice

先頭は'aaaaa[0]'で始まり、固定

上記条件を踏まえると、先頭から8文字を読み飛ばすだけでも要件は満たせますね。

var str = 'aaaaa[0][bbbbb][0][ccccc][0][ddddd]';
var str2 = 'aaaaa[0]' + str.slice(8).replace(/\[0(?=\])/g, '[1');

console.log(str2);  // "aaaaa[0][bbbbb][1][ccccc][1][ddddd]"

 String.prototype.indexOf

汎用性を上げたコード。

var str = 'hogeaaaaa[0][bbbbb][0][ccccc][0][ddddd]',
    a = 'aaaaa[0]',
    index = str.indexOf(a) + a.length,
    result = str.slice(0, index) + str.slice(index);

console.log(result);  // "hogeaaaaa[0][bbbbb][0][ccccc][0][ddddd]"

Re: tatsuno さん

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/04/29 20:40

    失礼致しました。
    自身の「分かっている範囲」と「分からない範囲」を具体化については、
    次回より気を付けたいと思います。

    コードについてはご教示頂き有難うございます。
    一度の正規表現で実現しようとばかりしていたので、
    この書き方は目からうろこでした。

    キャンセル

  • 2017/04/29 20:42

    むむ!置換の入れ子ができるんですね!
    勉強させていただきました!

    キャンセル

  • 2017/04/29 22:12

    親記事に別解のコードを追記しました。
    私が同じ状況なら String.prototype.indexOf のコードを使用すると思います。

    ただ、「aaaaa[0] が固定」が気にかかっていて、
    - 固定なら初めからなくてもいいのでは?
    - aaaaa[0]」と「aaaaa[0] 以降」を区切り文字で区切ってデータを分割すればいいのでは?(例: CSV)
    等、質問の根底を揺るがす方向に考えがいきます。
    フォーマットがあまり合理的ではない気がするのですよね…。

    キャンセル

+3

出現後の[0]の置き換えが固定個数ならできますが、[0]が任意個数存在するならできない気がします。

(?:aaaaa\[0\].*?)\[0\](.*?)\[0\]...       -> [1]\1[1]...

// これなら固定数のパターンは書けるのですが、任意個数の書きようがないと思います。


ちなみに...

  • aaaaa[0]の前に[0]が出現したとき
    質問者さんの方法では上記が置き換えられたままになってしまいます。例えば
    [0]aaaaa[0]->[1]aaaaa[0]
    ですが、これは質問文にかかれている仕様と違います。まずaaaaa[0]を探し、それ以降の部分文字列に対してのみ[0]->[1]の置き換えをして結果を連結するという方法でないといけないのでは?
    もしaaaaa[0]以前に[0]が出現しないならそれを前提として明記すべきと思います。
  • 置き換え対象パターン
    説明では[0]を[1]と書かれてますが、正規表現上では[数字の並び]を[1]へ置き換えるようになっています。自分は言葉で説明されている内容を仕様と解釈しました。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/04/29 20:25

    なるほど。

    一応、補足として付け加えたんですが、
    [0]の置き換えが任意個数を想定していたので、
    一発で置換は諦めようと思います。

    それにしても「?:」の表記は初めて知りました。
    勉強になります。

    キャンセル

  • 2017/04/29 20:34

    えーと・・・とりえあず、補足に書いたようなことは最初から質問に明記すべきです。
    これが書かれているかどうかで要件が違いますよね?それは回答者を混乱させる元ですし、要件が変わった前の質問文に回答した回答者に失礼と思います。(自分はいいですが・・・)。
    今後は気を付けた方がよいですよ。

    キャンセル

  • 2017/04/29 20:45

    質問する際の考慮が足りておりませんでした。
    以後、気を付けたいと思います。

    キャンセル

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

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

関連した質問

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