blogエダハノキ

気になるコトと知の整頓

調べ物メモ

-正規表現- 異なる文字列を一括置換してみた

更新日:

自分のサイトにリダイレクト設定を追加するにあたって、文字をたくさん打つことになったので少し工夫してみたよ。
今回はその覚え書き。

前置き

正規表現は英語にするとRegular Expression。
(参考)http://www-creators.com/archives/5402

JSの正規表現オブジェクトはこれを略してRegExp。
JS以外ではRegexという略称も用いられる。
regexの発音は自然に読めばリージェックス。
だけどレゲックスと読んだほうが略称っぽさが出ている感じがして好き。

それはさておき。

本題

やりたいことは一部のページのリダイレクト処理。ページ数はおよそ30。
うまい具合にパターン化できないため、今回は正規表現でリダイレクトの記述自体を簡略化するのが難しい。
でも手打ち作業はなるべく少なくしたい。

(i)正規表現を使えば、同じパターンの文字列置換をまとめて処理できる。

具体的な手順を見ていこう。

今回は.htaccessを編集してリダイレクトを行う。
特定のページに対して301リダイレクトをかけたいので以下のように記述する。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^現在のパス$ 変更後のパス [R=301,L]

これが約30ページ分必要になる。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^現在のパス1$ 変更後のパス1 [R=301,L]
RewriteRule ^現在のパス2$ 変更後のパス2 [R=301,L]
RewriteRule ^現在のパス3$ 変更後のパス3 [R=301,L]

RewriteRule ^現在のパス30$ 変更後のパス30 [R=301,L]

こんな感じ。
単純そうに見えるけど、実際にはパス1とパス2はまったく関連性のないURLなんだよね。

「現在1」と「変更後1」は繋がっているけど、「現在1」と「現在2」には何の関係もない。
「変更後1」と「変更後2」も無関係。

とにかく30通りの"RewriteRule 現在のパス$ 変更後のパス [R=301,L]"を用意しなければいけないわけで、結構手間がかかる。

ところが。

以前のリダイレクト設定をちょいちょいと修正すれば、今欲しい記述を完成させられることに気付いてしまった。
ふふふ、これで楽ができるぞ。

で、以前の設定がこれ。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^古いパス1$ 現在のパス1 [R=301,L]
RewriteRule ^古いパス2$ 現在のパス2 [R=301,L]
RewriteRule ^古いパス3$ 現在のパス3 [R=301,L]

RewriteRule ^古いパス30$ 現在のパス30 [R=301,L]

この「現在のパス」というのが今回使い回せる部分であり「古いパス」は不要な部分になる。

正規表現を自分の頭で考えながら使うのは初めてのことだから横着せずに一つずつ進めていく。

ちなみにこの作業にはSublime Text3というテキストエディタを使っているよ。
普段使っているTeraPadは正規表現を用いた文字列置換ができないらしい。

手始めに、RewriteRuleの後ろの「半角スペース」と「^古いパス$」を削除したい。

検索窓に以下を入力。$の後ろの半角スペースまで指定する。

RewriteRule \^.*\$ 

これで狙い通りの箇所が選択される。
置換する文字列は以下。

RewriteRule ^

結果はこうなる。

RewriteRule ^古いパス$ 現在のパス [R=301,L]

RewriteRule ^現在のパス [R=301,L]

検索にヒットした箇所を一括置換すれば、30行にわたる記述がまとめて修正される。
実に便利。すごいぞ正規表現。

次に$を書き足す。正規表現はここでは必要ない。

検索。[の前の半角スペースまで指定する。

 [R=301

置換。

$  [R=301

結果はこう。

RewriteRule ^現在のパス [R=301,L]

RewriteRule ^現在のパス$ [R=301,L]

ここまで来たらあとは変更後のパスを手作業でコピペしていって完了だね。
その場合は置換で$の後ろに半角スペースをもう一つ入れるのもいい。

ところが!

幸運なことに、今回は正規表現の出番がまだ残っていた。

実は今回URLを大きく変えたわけではなくて、「現在のパス」と「変更後のパス」はあまり違いがなかったりする。

つまり。

RewriteRule ^現在のパス$ 現在のパス [R=301,L]

この形さえ作れれば手打ち作業はほとんど必要ないということ。
さあ、やってみよう。

検索。

RewriteRule \^(.*)\$

置換。

RewriteRule ^$1$ $1

結果。

RewriteRule ^現在のパス$ [R=301,L]

RewriteRule ^現在のパス$ 現在のパス [R=301,L]

そしてこれらの置換をすべて一括で行った結果。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^現在のパス1$ 現在のパス1 [R=301,L]
RewriteRule ^現在のパス2$ 現在のパス2 [R=301,L]
RewriteRule ^現在のパス3$ 現在のパス3 [R=301,L]

RewriteRule ^現在のパス30$ 現在のパス30 [R=301,L]

こうなる。
もうほとんど完成形。
スゴイ。正規表現カッコイイ。

あとは手動でやらざるを得ない部分を書き換えて作業終了。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^現在のパス1$ 変更後のパス1 [R=301,L]
RewriteRule ^現在のパス2$ 変更後のパス2 [R=301,L]
RewriteRule ^現在のパス3$ 変更後のパス3 [R=301,L]

RewriteRule ^現在のパス30$ 変更後のパス30 [R=301,L]

ウェブ検索でここまで辿り着くのには苦労したけど、正規表現の便利さを実感できて満足。
また機会を見つけて、調べたり試したりしつつ知識を増やしていけるといいな。

本文は以上!
このあとは補足だよ。

使用した正規表現の意味

任意の文字列とマッチ

.*

"."と"*"を組み合わせて、なんらかの文字が0個以上並んでいることを表す。
内容が不規則でパターン化できない箇所を選択するのに使える。

エスケープ

\

直後の文字をただの文字として扱う。
^や$は正規表現の記法において特別な意味を持つため、ただの文字として検索させるにはエスケープが必要。

グループ化(変数化)

()

()内をグループと見なす。
置換内容に$1や$2を記述するとグループが呼び出される。

グループ呼び出し(変数呼び出し)

$1,$2,$3,…

置換結果にグループを呼び出す。
グループが複数あるときは番号で使い分ける。

おまけ。一回の置換で済ませる書き方

工程を分けずにまとめて置換することもできる。
ここに書き残したところで使う機会はもうないだろうけどね。

検索。

\^.*\$ (.*) \[R=301

置換。

^$1$ $1 [R=301

結果。

RewriteRule ^古いパス$ 現在のパス [R=301,L]

RewriteRule ^現在のパス$ 現在のパス [R=301,L]

こうして振り返ると本文中ではかなり回りくどいやり方をしていたとわかるね。

以上、ではまた!

-調べ物メモ
-,

Copyright© blogエダハノキ , 2019 All Rights Reserved Powered by STINGER.