JavaScript専用
他の言語とも、ある程度の共通点はある。
"\ "と"\ "
本ページ内では、バックスラッシュ "\ " と円マーク "\ " は完全に同等 な文字。その場で使用しているフォントが欧文用か和文用かの違いで、表示だけが異なる。
動作確認ブラウザ
次の4種のみ。Chrome 78.0.3904.108, Firefox 70.0.1, Edge 44.18362.449.0, IE11 11.476.18362.0(2019-11月時点での最新版)。各所に示した非対応ブラウザ名は、この範囲内に限っている。
用語
難解な専門用語の使用は避け、広義の一般用語や適当な造語で言い換えている部分が多数ある。勉強用には適さないので要注意。
正規表現の利用方法:
多くの文字を含む原稿
$\mathcal{Original}$
の中から特定の文字列を検索するとき、その文字列が満たすべき条件を
$\mathcal{Regexp}$
で指示し、処理結果を
$\mathcal{Result}$
として得たい場合、上記のリンク先に示すような各種の JavaScript コマンドが使用される。
検索したい文字列は、それをそのままの形で指示すれば済むこともあるが、曖昧で複雑な条件がからんでくることも多い。この複雑な条件を短い簡潔な書式で記述したものが
$\mathcal{Regexp}$
で、この書式を
正規表現 (Regular Expression)という。
以下、それぞれのコマンドの概要と、その処理結果を示す。この処理では、原稿や正規表現などの内容を次のように設定している。原稿中の "も曇", "は雨" のいずれか ("
| ") に該当する文字列を、すべて ("
g " :
以降、 g オプションと呼ぶ ) 拾い出す例である。
var
$\mathcal{Result}$ ; // (検索結果が入る)
var
$\mathcal{Original}$
= "長崎は今日も曇だった。明日は雨に違いない。 ";
var
$\mathcal{Regexp}$
= /も曇 |は雨 /g; // (書式1 )
または var
$\mathcal{Regexp}$
= new RegExp("も曇 |は雨 ","g"); // (書式2 )
var
$\mathcal{N\!ewstr}$
= "も晴 "; //( replaceコマンドに使用) もっと詳しく
$\boldsymbol{\mathcal{Result}}$ の形式:
処理の結果が入るが、コマンドの種類によりデータ形式が異なる。exec,match ⇒混成配列のようなもの 、matchAll ⇒文字列行列のようなもの 、split ⇒文字列配列、toString,replace ⇒文字列、search ⇒数値、test ⇒論理値。 詳細については各コマンドの欄を参照。
$\boldsymbol{\mathcal{Regexp}}$
の2つの書式:
よく使われるのは
書式1 。ただ、この書式の右辺について、「"」と「"」で囲んで示されるような単なる文字列ではないことに留意すべき。$\mathcal{Str}$
="/ も曇
| は雨
/g" のように、正規表現的に記述された文字列が与えられていても、
$\mathcal{Regexp}$ = $\mathcal{Str}$ とするだけでは期待した結果は得られない。
この場合でも、
eval(" $\mathcal{Regexp}$ = " + $\mathcal{Str}$
+ ";"); とすることで目的は達せられるが、
eval の使用を避けたい場合に
書式2 を使う。例えば、$\mathcal{Str}$ 内に余計な"
/ "が含まれていなければ、
$\mathcal{Arg}$
= $\mathcal{Str}$
.split (/\//); $\mathcal{Regexp}$ = new RegExp( $\mathcal{Arg}$
[1], $\mathcal{Arg}$
[2]); とする。
ただし、書式2や
eval の場合には、$\mathcal{Str}$ の中の"
\ "は、"
\\ "のように適切に
エスケープ されている必要がある。
間接記述/直接記述:
このページの例では、例えば、
$\mathcal{Result}$ = $\mathcal{Original}$ .match( $\mathcal{Regexp}$ );
のように、間接的な記述に統一しているが、次のように直接的に書くこともできる。
$\mathcal{Result}$ =" 長崎は・・・違いない。".match(/ も曇|は雨/g);
しかし、次の点に注意が必要である。
注意: 直接記述の exec や test コマンドでは、g オプションをつけて繰り返し実行させ全数検索しようとしても、検索位置が先に進まず、繰り返しループから抜け出せなくなる。1回だけの実行なら問題ないが、exec や test コマンドは複数回実行するケースが多いので、間接記述にしておく方が無難である。
$\boldsymbol{\mathcal{N\!ewstr}}$ の書式:
replace コマンドを使うことにより、検索で得られた文字列を $\mathcal{N\!ewstr}$ と置き換えることができる。ここでは、単純な文字列("も晴")との置き換えの例だけを示しているが、実際には、さらに複雑な指示も可能である。
$\mathcal{Result}$ = $\mathcal{Regexp}$ .exec( $\mathcal{Original}$ );
得られる情報量は最も多いが、取り扱いが煩雑。処理時間もかかりそう。
$\mathcal{Result}$
は複数の情報の集まりで、検索された文字列の内容や、その文字列が
$\mathcal{Original}$ のどこに位置するかの情報(
index )などが出力される。該当文字列が無いときは
$\mathcal{Result}$ = null となる。
書式上、
$\mathcal{Regexp}$ は式の右辺にあり、出力先のようには見えないが、上記とは別の位置情報(
lastIndex )などが書き込まれる。
しかし、このコマンドは、一回の実行だけでは、最初に見つけた1つの文字列の情報しか出力しない。該当するすべての文字列を拾い出すためには、繰り返し処理が必要となる。
もっと詳しく
結果として得られる各種情報の内容
$\mathcal{Result}$ ....... [検索された文字列,
グループ化記録 1, 2, ... n]
文字列配列 文字列がヒットしないときは
null となる。
そのときは、下記の $\mathcal{Result}$ 系の全情報へのアクセスは不可。
$\mathcal{Result}$ [0] ... 検索された文字列
文字列
$\mathcal{Result}$ [1] ... グループ化記録1
文字列
$\smash{\vdots}$
(n: グループ化の括弧の数。10以上でも可)
$\mathcal{Result}$ [n] .... グループ化記録n
文字列
$\mathcal{Result}$ .index ... 検索された文字列の原稿中での
左端の位置 数値
arguments[] 風の
[n+1] による指定は不可。
$\mathcal{Result}$ .input ... 原稿全体の文字列
文字列
arguments[] 風の
[n+2] による指定は不可。
$\mathcal{Result}$ .groups. $\mathcal{N\!ame}$ ...
名前付きグループ化記録 の内容
文字列
それぞれ異なる名前(
$\mathcal{N\!ame}$ )に対応した記録内容。
名前付きが無いときは
$\mathcal{Result}$ .groups は
undefined 。
. $\mathcal{N\!ame}$ を付けての呼び出しはエラーとなる。
名前付きが有るときは
for(var k in $\mathcal{Result}$ ) での
$\mathcal{Result}$ [k] の一括呼び出しは使えない(エラー)。
以下の8項目の情報は、間接記述で $\mathcal{Regexp}$ が定義済の場合のみ有効。
$\mathcal{Regexp}$ .lastIndex ...
g オプション有:検索された文字列の原稿中での
右端の位置 数値 同時に、
次の検索の開始点 でもある。
すべてを検索し終えると0にリセットされる。
必要に応じ、代入によって任意の値への
書き替えも可 。
これにより、検索開始点の意図的な操作が可能。
g オプション無:通常は0。
書き替えても、検索開始点は操作できない。
検索完了後もリセットされず、書き替えた値のまま。
$\mathcal{Regexp}$ .source ...
正規表現本体 の文字列
文字列
わざわざこの方法で取得しなくても、一般には既知の内容。 これも含め、以降の $\mathcal{Regexp}$ 系の利用価値は低い。
$\mathcal{Regexp}$ .global ...
g オプションの有/無(
true/false )
論理値
$\mathcal{Regexp}$ .ignoreCase ...
i オプション の有/無
論理値
$\mathcal{Regexp}$ .multiline ...
m オプションの有/無
論理値
$\mathcal{Regexp}$ .dotAll ...
s オプションの有/無
論理値
$\mathcal{Regexp}$ .unicode ...
u オプションの有/無
論理値
$\mathcal{Regexp}$ .sticky ...
y オプションの有/無
論理値
以下の6項目の情報は、間接記述でも直接記述でも有効。
しかし、ヒットした文字列がないときには更新されず、以前の古い情報が残る。
現在、これらの機能は非推奨になっている。使用は避けるのが賢明。
RegExp.\$1 ~
.\$9 ... グループ化記録1~9(10以上は呼び出せない)
文字列
RegExp.lastMatch ... 検索された文字列(一説にある
.$& は不可)
文字列
RegExp.leftContext ... 検索文字列の前にある全原稿(
.$` は不可)
文字列
RegExp.rightContext ... 検索文字列の後にある全原稿(
.$' は不可)
文字列
RegExp.lastParen ... 最大番号のグループ化記録(
.$+ は不可)
文字列
RegExp.input ... 原稿全体の文字列(
.$_ は不可)
文字列
繰り返し実行時の注意
一回のコマンドの実行では、1つの文字列しか処理できないので、
while ループなどを使って繰り返し実行させることが多い。
$\mathcal{Result}$ == null によって全てを検索し尽くしたことを判断し、ループから脱出することになるが、注意しないと無限ループに陥り、ブラウザがフリーズしてしまうことがある。
注意1 : 正規表現には必ず
g オプションを付ける。さもないと、最初に現れる該当文字列を繰り返して探し続けることになり、
$\mathcal{Result}$ == null の条件が永遠に満たされない。
注意2 :
/^/g, /$/g, /()/g のような無意味な正規表現を指示しない。指示すると、
lastIndex が行頭や行末に固定されたまま無駄な実行が繰り返される。
本ページの「使ってみる」の舞台裏では、この
exec コマンドが動作しているが、これらのフリーズの実体験はできない(回避対策済)。
例による実行結果の一部(検索された文字列,
位置 (
index,lastIndex )):
1回目 も曇,
5,7 、 2回目 は雨,
13,15 、 3回目 null,
-,0
$\mathcal{Result}$ = $\mathcal{Regexp}$ .test( $\mathcal{Original}$ );
得られる情報量は少ないが、たぶん処理は速い。詳細処理前の篩分け用に有効か。
$\mathcal{Result}$
は単一の論理変数で、
$\mathcal{Regexp}$ で指示した文字列が見つかれば
true 、何も見つからなければ
false となる。推奨されている正攻法だけでは具体的な文字列の内容は分からないが、位置(
lastIndex )は取得できる。
exec コマンドと同様、一回の実行だけでは、最初に見つけた1つの文字列についての情報しか得られない。該当するすべての文字列を確認するには、繰り返し処理が必要となる。
もっと詳しく
結果として得られる各種情報の内容
$\mathcal{Result}$ ....... 検索された文字列の有/無(true/false ) 論理値 これ以外の $\mathcal{Result}$ 系の全情報はundefined 。
$\mathcal{Regexp}$ 系の全情報 ... exec コマンドと全く同じ。
RegExp 系の全情報 ... exec コマンドと全く同じ。
繰り返し実行時の注意
exec コマンドと同じ。ただし、while ループからの脱出は $\mathcal{Result}$ == false による。
例による実行結果(該当文字列の有無,
位置 (
lastIndex )):
1回目
true, 7 、 2回目
true, 15 、 3回目
false, 0
$\mathcal{Result}$ = $\mathcal{Regexp}$ .toString( );
使う機会はあまりなさそう。
$\mathcal{Regexp}$ の正規表現を、文字列として
$\mathcal{Result}$ に出力するだけ。書式2で記述している場合でも、
書式1 の形式で出力される。
もっと詳しく
結果として得られる各種情報の内容
$\mathcal{Result}$ ............ 正規表現全体の文字列 文字列
$\mathcal{Result}$ [0] ....... 正規表現文字列の1文字目 文字
$\smash{\vdots}$ (n: 正規表現全体の文字数)
$\mathcal{Result}$ [n-1] ... 正規表現文字列のn文字目 文字
$\mathcal{Regexp}$ 系の情報 ... exec コマンドの場合と同じ。ただし、 lastIndex は、コマンド実行前後で変化なし。
RegExp 系の情報 ... 全く更新されず、以前の値が残ったまま。
例による実行結果: /も曇 |は雨 /g
$\mathcal{Result}$ = $\mathcal{Original}$ .match( $\mathcal{Regexp}$ );
一回の実行だけで該当文字列のすべてを拾い出せて効率的。
$\mathcal{Regexp}$ の中に全数検索の指示(
g オプション)があれば、1回のコマンドの実行だけで、
該当するすべての文字列が配列
$\mathcal{Result}$
に出力される。全数検索が指示されていないときには、最初に見つかった文字列の情報が出力されるだけとなる。
もっと詳しく
結果として得られる各種情報の内容
$\boldsymbol{\mathcal{Result}}$ 系(g オプション有のとき)
$\mathcal{Result}$ ....... [検索された文字列1, 2, ... m]
文字列配列 文字列がヒットしないときは
null となる。
そのときは、下記の $\mathcal{Result}$ 系の全情報へのアクセスは不可。
$\mathcal{Result}$ [0] ... 検索された最初の文字列
文字列
$\mathcal{Result}$ [1] ... 検索された2番目の文字列
文字列
$\smash{\vdots}$
(m: 検索できた文字列の個数)
$\mathcal{Result}$ [m-1] .... 検索された最後の文字列
文字列
これ以外の
$\mathcal{Result}$ 系は無効。
$\boldsymbol{\mathcal{Result}}$ 系(g オプション無のとき) ...
exec コマンドの場合と殆ど同じ。
$\mathcal{Result}$ ....... [検索された文字列,
グループ化記録 1, 2, ... n]
文字列配列 文字列がヒットしないときは
null となる。
そのときは、下記の $\mathcal{Result}$ 系の全情報へのアクセスは不可。
$\mathcal{Result}$ [0] ... 検索された文字列
文字列
$\mathcal{Result}$ [1] ... グループ化記録1
文字列
$\smash{\vdots}$
(n: グループ化の括弧の数。10以上でも可)
$\mathcal{Result}$ [n] .... グループ化記録n
文字列
これ以外の
$\mathcal{Result}$ 系も有効で、その内容は
exec コマンドの場合と同じ。
以下の情報は、間接記述で $\mathcal{Regexp}$ が定義済の場合のみ有効。
しかし、読み取り や 一部の書き替え はできるものの、殆ど役には立っていない。
$\mathcal{Regexp}$ .lastIndex ...
g オプションに関係なく、書き替えによる検索開始点の操作は不能。
g 有り なら、コマンド実行後、ヒットの有無に関わらず0にリセット。
g 無し なら、コマンド実行前後で変化なし。
これ以外の
$\mathcal{Regexp}$ 系は
exec コマンドの場合と全く同じ。
RegExp 系も
exec コマンドの場合と全く同じ。
ただし、
g 有り で得られる情報は最後のヒットによる更新値だけ。
例による実行結果: も曇, は雨
$\mathcal{Result}$ =[... $\mathcal{Original}$ .matchAll( $\mathcal{Regexp}$ )];
一回の実行だけで match よりもさらに多くの情報が拾い出せる。非対応ブラウザ:Edge, IE11 。
例示した処理結果からだけでは、
match コマンドとの差異は認められないが、
g オプション付きで
グループ化記録 を使用している場合、その違いがはっきりと現れる。ヒットしたすべての文字列はもちろん、それぞれに対応したグループ化記録の全体が一度に取得できる。
もっと詳しく
結果として得られる各種情報の内容
$\mathcal{Result}$ ... 下記の行列が全1行に変成された情報。
文字列行列
[検索された文字列1, そのグループ化記録$\text{1}_{\text{1}}$, $\text{1}_{\text{2}}$, ... $\text{1}_{\text{n}}$]
[検索された文字列2, そのグループ化記録$\text{2}_{\text{1}}$, $\text{2}_{\text{2}}$, ... $\text{2}_{\text{n}}$]
$\smash{\vdots}$ (m: ヒットした文字列の個数)
$\smash{\vdots}$ (n: グループ化の括弧の数。10以上でも可)
[検索された文字列m, そのグループ化記録$\text{m}_{\text{1}}$, $\text{m}_{\text{2}}$, ... $\text{m}_{\text{n}}$]
一つもヒットしなかったときは ""(空文字) となる。
そのときは、下記の $\mathcal{Result}$ 系の全情報へのアクセスは不可。
$\mathcal{Result}$ [0] ...... 上記行列の1行目
文字列配列
各要素の呼び出しは下記による。以下も同様。
$\mathcal{Result}$ [0][0],[0][1],[0][2],...[0][n]
$\mathcal{Result}$ [1] ...... 上記行列の2行目
文字列配列
$\smash{\vdots}$
(m: ヒットした文字列の個数)
$\mathcal{Result}$ [m-1] ... 上記行列の最後の行
文字列配列
これ以外の
$\mathcal{Result}$ 系は無効。
$\mathcal{Regexp}$ .lastIndex ...
g オプションの有無により異なる。
g 有り なら、この値を書き替えて検索開始点の操作が可能。
g 無し では、書き替えの効果なし。検索は常に最初から。
g に関係なく、この値はコマンド実行前後で変化なし。
これ以外の
$\mathcal{Regexp}$ 系は
exec コマンドの場合と全く同じ。
RegExp 系も
exec コマンドの場合と全く同じ。
ただし、
g 有り で得られる情報は最後のヒットによる更新値だけ。
参考( コマンドの書式を囲む [... ] について ) (スプレッド構文)
"... "で各要素を分離し、集積した結果を"[ ] "で再配置。
例による実行結果: も曇, は雨
$\mathcal{Result}$ = $\mathcal{Original}$ .search( $\mathcal{Regexp}$ );
得られる情報量は少ないが、たぶん処理は速い。詳細処理前の篩分け用に有効か。
$\mathcal{Result}$
は、
$\mathcal{Original}$ 内の最初の該当文字列の位置(
index )を示す単一の数値出力である。
$\mathcal{Regexp}$ で全数検索の指示をしていても、最初の文字列以外の情報は得られない。何も見つからなかったときには
-1 が出力される。
もっと詳しく
結果として得られる各種情報の内容
$\mathcal{Result}$ ...... 検索された文字列の、原稿中での
左端の位置 数値 文字列がヒットしないときは
-1 となる。
これ以外の
$\mathcal{Result}$ 系は無効。
$\mathcal{Regexp}$ .lastIndex ...
この値を書き替えても検索開始点の操作はできない。
この値はコマンド実行前後で変化はない。
これ以外の
$\mathcal{Regexp}$ 系は
exec コマンドの場合と全く同じ。
RegExp 系も
exec コマンドの場合と全く同じ。
例による実行結果(最初の該当文字列の
位置 (
index )):
5
$\mathcal{Result}$ = $\mathcal{Original}$ .replace( $\mathcal{Regexp}$ , $\mathcal{N\!ewstr}$ );
文字列の加工用として頻繁に使われる。
$\mathcal{Original}$
の中にある
$\mathcal{Regexp}$
で指示された文字列が、文字列
$\mathcal{N\!ewstr}$
と置き換えられて、単一の文字列変数
$\mathcal{Result}$
に出力される。なお、
$\mathcal{N\!ewstr}$ は単純な文字列だけとは限らず、その中で、検索過程から得られた
記録を利用 したり、JavaScript の任意の関数を記述することもでき、より複雑な置き換えも可能である。全数検索の指示(
g オプション)が無い場合には、最初の該当部分だけの置き換えとなる。
もっと詳しく
結果として得られる各種情報の内容
$\mathcal{Result}$ ...... 置き換え処理後の原稿 文字列 ヒットしなかったときは 原稿 $\mathcal{Original}$ のまま。$\mathcal{Result}$ [0] ...... $\mathcal{Result}$ の1文字目 文字
$\mathcal{Result}$ [1] ...... $\mathcal{Result}$ の2文字目 文字
$\smash{\vdots}$ (n: $\mathcal{Result}$ の文字数)
$\mathcal{Result}$ [n-1] ... $\mathcal{Result}$ のn文字目 文字
これ以外の$\mathcal{Result}$ 系は無効。
$\mathcal{Regexp}$ .lastIndex ...
この値を書き替えても検索開始点の操作はできない。
コマンド実行後は0にリセットされる。
これ以外の $\mathcal{Regexp}$ 系は exec コマンドの場合と全く同じ。
RegExp 系も exec コマンドの場合と全く同じ。
ただし、得られる情報は最後のヒットによる更新値のみ。
$\boldsymbol{\mathcal{N\!ewstr}}$ の書式
例による実行結果: 長崎は今日も晴だった。明日も晴に違いない。
$\mathcal{Result}$ = $\mathcal{Original}$ .split( $\mathcal{Regexp}$ );
CSVデータなどの加工に便利で、良く使われる。
$\mathcal{Regexp}$
で示された文字列を区切り記号とみなして、
$\mathcal{Original}$ をバラバラに分割し、配列
$\mathcal{Result}$
に出力する。全数検索の指示(
g オプション)がなくても、すべての該当部分で分割される。
なお、ここに示した実行例の
$\mathcal{Regexp}$ は、
split コマンド用としては複雑すぎて適切ではない。一般には、例えば、英文の英単語への分割には "
\s " などの簡単な区切り記号が使われる。
もっと詳しく
結果として得られる各種情報の内容
$\mathcal{Result}$ ... 分割された文字列のリスト 文字列配列
区切り記号は削除されている。しかし、 $\mathcal{Regexp}$ 内の区切り記号を( ) で囲むと、
グループ化記録の内容として $\mathcal{Result}$ に混入してしまう。
$\mathcal{Result}$ [0] .... 分割された最初の文字列 文字列
原稿の最初が分割記号のときは、""(空文字)。
$\mathcal{Result}$ [1] .... 分割された2つ目の文字列 文字列
$\smash{\vdots}$ (n: 分割記号の個数)
$\mathcal{Result}$ [n] .... 分割された最後の文字列 文字列
原稿の最後が分割記号のときは、""(空文字)。
これ以外の$\mathcal{Result}$ 系は無効。
$\mathcal{Regexp}$ .lastIndex ...
この値を書き替えても検索開始点の操作はできない。
この値はコマンド実行前後で変化はない。
これ以外の $\mathcal{Regexp}$ 系は exec コマンドの場合と全く同じ。
RegExp 系も exec コマンドの場合と全く同じ。
ただし、得られる情報は最後のヒットによる更新値のみ。
例による結果: 長崎は今日, だった。明日, に違いない。
文字位置の数え方
半角文字やスペースはもちろん、改行・タブ・全角文字なども、それぞれを一文字と数える。ただし、使用頻度が少ない全角文字には、まれに二文字と数えるものもある(例:"𠀋"などのサロゲートペア文字)。
position.0
A
position.1
B
position.2
C
position.3
D
position.4
E
position.5
F
position.6
$\mathcal{Original}$ の文字列が "ABCDEF" で、$\mathcal{Regexp}$ に よって指定された文字列が"CD"のとき、結果 として得られる位置情報は次のとおり。 index : "CD"の左端の2。 lastIndex : "CD"の右端の4。
正規表現の基本書式:
$\boldsymbol{\mathcal{Regexp}}$ = / 正規表現本体 / オプション
正規表現本体 :
記述の基本
検索すべき文字列の多様な構成を想定し、それらにマッチするように、以下にあげる各種の記法を並べて、正規表現の本体を記述する。
例: 原稿から、電話番号らしき部分を全て抽出する。
電話番号であることを宣言する記号はさまざま。番号の途中にはハイフンが入る場合もあるし、無い場合もある。また、都会と地方では局番の桁数が違うなど、色々と考慮して、とりあえず、
/(電話:|TEL:|☎ )?\d {2,4}-? \d{2,4} -?\d{4}(?!\d) /g
原稿に想定外の記述があって、誤検索が多ければ、必要に応じて工夫・修正を加える。
文字・文字列
.
何らかの一文字(スペースや漢字も含む。
sオプション を付けたときに限り、改行文字
\n ,
\r も含む)。正規表現の中でも最強の記号。
「一文字」とは言っても、この後に
?, *, +, {, } などを組合せて続ければ、多文字の文字列をも表現できる。しかも、任意の同一文字が単純に連なっただけの文字列ではなく、一文字ずつが異なる文字でも良いことに注目(
これは、 \d ,
\s ,
\w などの他の多役文字でも同様 )。
[ ABC ]
"
A " か "
B " か "
C " かの一文字。 =
A | B | C 。
\?, \d, \uhhhh など複数個で構成されている特殊文字は、まとめて一文字とみなす。
なお、[ ] 内では、下記以外の正規表現用の予約文字は機能しないので注意。
「 "^", "-", "\"
」 や
「 \u{hhhhh} の中で使われる "{", "}"
」 使用すると、
[1] 単なる文字としてしか認識されない、
[2] 無視される、
[3] エラーになる、のいずれか(
下記の2件でも同様 )。最初から単なる文字として使うつもりなら、頭に
"\" を付けておくのが無難。
[^ ABC ]
"A " でも "B " でも "C " でもない一文字。
[ A - C ]
"
A " から "
C " までのいずれかの一文字("
A ", "
B ", "
C ")。範囲は文字コード順で指定。半角英大文字は A,B,C,...,Z 順、半角英小文字は a,b,c,...,z 順、半角数字は 0,1,2,...,9 の順。和文字でも可能だが、コード配列が素直でないので要注意(
参考 )。
AB | CD
文字列 "AB " あるいは "CD "。2択だけとは限らず、A|BC|DEF なども可。また、それぞれの選択肢は、単純な文字列に限らず、正規表現の複雑な表記でも良い。
場合によっては、選択肢の記述順序で結果が変わることもある。選択肢は左のものから順番に評価されていき、該当するものが見つかると、それより右の評価はスキップされてしまう。それゆえ、"ab|abc" では "ab" にしかヒットせず、"abc|ab" では "abc" の中の "ab" は見向きもされない。
次は、正規表現用の予約文字を、本来の見たままの文字として扱うときの処置(エスケープ)
\?
予約文字の前に"\"を付ける。"? "部分に使える文字には、?, /, ., ,, \, (, ), [, ], {, }, ^, \$, -, +, *, <, =, !, | がある。
\を付けなくても本来の文字として認識される場合もあるが、前後の文字の種類によっても左右される。必ず\を付けるようにしておくのが確実。
しかし、不必要なものにまで\を付けると、以下に示すように、普通の文字が特殊機能を持つ文字に変わってしまうので要注意。
以下、一般の文字を、特殊な機能を持つ文字として転用するもの
\d
0~9 のいずれかの半角数字。= [0-9] 。
\D
\d に該当しないすべての文字。= [^\d] 。
\s
半角スペース, 全角スペース,
\t ,
\v ,
\n ,
\r ,
\f の いずれかの文字。=
[ \t\v\n\r\f] 。
\S
\s に該当しないすべての文字。= [^\s] 。
\w
半角英文字, 半角数字, _(アンダーバー)のいずれかの文字。= [A-Za-z0-9_] 。
\W
\w に該当しないすべての文字。= [^\w] 。
\p{sc=Hira}
全角ひらがな のいずれかの文字。使用には
uオプション が必要。≒
[ぁ-ゟ] 。"ぁ" は小さい "あ"、"ゟ" は「より」で変換。
非対応ブラウザ:Firefox, Edge, IE11 。
\p{sc=Kana}
全角カタカナのいずれかの文字。使用には
uオプション が必要。なお、長音 "ー", 中黒 "・" は含まれない。含めるときは、\p{sc
x =Kana}、あるいは ≒
[゠-ヿ] 。"゠" はダブルハイフン(IMEパッドからU+30A0)、"ヿ" は「こと」で変換。
非対応ブラウザ:Firefox, Edge, IE11 。
\p{sc=Han}
全角漢字のいずれかの文字。使用には
uオプション が必要。日本語では使わない漢字も含む。括弧類,句読点などは含まれない。
非対応ブラウザ:Firefox, Edge, IE11 。
以下の中で、一般の原稿を扱う上で必要なのは "\n", "\r", "\t" 程度。その他はおまけ。
\0
Null文字(NUL)。ただし、直後に数字を続けないこと。続けると2桁8進codeと誤認される。\0 よりも \000(2桁8進codeでのNull文字)を使う方が確実。"0" はオーではなくゼロ。= \x00 。
\0oo
2桁8進codeで表される一文字。例:制御文字。"o" は8進数の一文字。"0" はオーではなくゼロ。
\xhh
2桁16進codeで表される一文字。例:半角英数字。"h" は16進数の各一文字。 一般には、検索すべき文字をそのまま記述すれば済むので、わざわざコードで表現しなければならない機会は少ないはず(次に続く2件も同様 )。
\uhhhh
4桁16進Unicodeで表される一文字。例:全角文字。
\u{hhhhh }
5桁16進Unicodeで表される一文字(サロゲートペア文字)。4桁のUnicodeでは表現できない希少文字。例:𠀋 = \u{2000b} 。ただし、この書式を使うときには
uオプション が必要。
この書式は、4桁未満の16進文字codeとしても使える。例:\xhh = \u{hh} 。
非対応ブラウザ:IE11 。
\cG
ctrl-G に相当する制御文字。G 部分を G, H, I, J, K, L, M にすると下記の制御文字と同等。ただし、\c@(一般にはNull文字) は使えない。
\n
改行(LF)。= \cJ , \012 , \x0a 。
\r
改行(CR)。= \cM , \015 , \x0d 。
\t
水平タブ(HT)。= \cI , \011 , \x09 。
\v
垂直タブ(VT)。= \cK , \013 , \x0b 。
\f
改ページ(FF)。= \cL , \014 , \x0c 。
[\b]
後退(BS)。単語境界の
"\b" とは異なるので要注意。=
\cH ,
\010 ,
\x08 。
\x07
ベル文字(BEL)。一般には"\a"のはずだが、なぜか認識されない。代わりに"\x07"などを使う。= \cG , \007 。
グループ化
(AB|CD )
括弧の内部を、前後にある文字列から仕切って
一体化 (多重括弧も可)。
例: ab
( cd
) {2} = abcdcd,
( ab
( cd
) {2}
) {2} = abcdcdabcdcd 。({2}については
こちら )。
さらに、内部の該当文字列の内容を一時メモリーに
記録 。記録の呼び出し方法は
こちら 。
(?<name >AB|CD )
名前付きの一体化と記録。記録番号だけではなく、名前(ここではname)による
呼び出し もできるようになる。
ただし、
$\mathcal{Regexp}$ や
$\mathcal{N\!ewstr}$ の中から呼び出すだけなら問題はないが、使用するコマンドの種類によっては、実行後の
$\mathcal{Result}$ による呼び出しには制限がかかることがある。
非対応ブラウザ:Firefox, Edge, IE11 。
(?:AB|CD )
内容は記録させず、一体化するだけ。
配置の条件
(アンカー)
以下の単独文字 A は、文字列との置き換えも可能。
^A
1行目の行頭にある文字"
A "(言い換えれば、原稿の最初にある文字"
A ")。2行目以降の行頭も検索対象にするときには、
mオプション が必要。
"
[^ ] " の中の否定を表す "^" とは無関係。
A \$
最終行の改行無しの行末にある文字"
A "(すなわち、改行文字も含めて、原稿の最後尾にある文字が検索対象になる)。全行の改行付きの行末も検索対象にするときには、
mオプション が必要。
"
\$1 " の中の記録番号を表す "\$" とは無関係。
AB (?=CD )
文字列"AB "(ただし、後 に文字列"CD "が続く場合に限る )。なお、"CD "は検索結果の文字列には含まれず、グループ化記録の対象にもならないし、引き続きの検索を指示しているときでも、次の検索は"AB "の右側の端から始まる(次に続く3件も同様 )。
そのため、"AB" の部分を、 ".?" のような0個の文字数をも許容する表現に変えると、その位置にマッチし続けて、検索が先に進まなくなるので要注意。
(?<=CD )AB
文字列"AB "(ただし、前 に文字列"CD "がある場合に限る )。
非対応ブラウザ:Firefox, Edge, IE11 。
AB (?!CD )
文字列"AB "(ただし、後 に文字列"CD "が続く場合は除く )。
(?<!CD )AB
文字列"AB "(ただし、前 に文字列"CD "がある場合は除く )。
非対応ブラウザ:Firefox, Edge, IE11 。
\b
単語境界 を表す。単語境界とは、
「 半角英数字と "_"
」 以外の文字(=
\W )に、原稿の最初の文字の左,最後の文字(改行文字のこともあり)の右も加えたもの。ただし、"\b"そのものは検索結果の文字列には含まれない。和文には役立たない。なお、\b ≠
[\b] 。
"/
\bday \b |
day \b|
\bday /g" のとき、"
day ,x,Sun
day ,y,
day light" のように、各色の対応部分がヒット。
\B
"\b" 以外、すなわち非単語境界 を表す。ただし、"\B"そのものは検索結果の文字列には含まれない。和文には役立たない。
"/\Bday \B |day \B |\Bday /g" のとき、"7day s,Sunday ,y,day light" のように、各色の対応部分がヒット("\b" とは青/茶が逆転)。
繰り返し回数
指定文字として使っている下記の "." は、他の文字や、グループ化された文字列との置き換えも可能。
. ?
1個以下の指定文字(0個も含む)。つまり、有っても無くてもよい一文字。 =
{0,1} 。ab?c =
ac|abc 。
"
*? ", "
{ }? ", "
(?: ) " などに含まれる 最短一致や記録除外を表す "?" とは無関係。
. *
任意個数の指定文字の列(0個でも可 )。".*" の前と後にある文字に挟まれた、最長 の指定文字の列。= {0,} 。
"/<.*>/" の場合、ABC<DEF>GHI<JKL> MNO のように赤色部分がヒット。
. *?
".*" に該当する候補のうち、最短 の指定文字の列。
"/<.*?>/" の場合、ABC<DEF> GHI<JKL>MNO のように青色部分がヒット。
. +
任意個数の指定文字の列(ただし、0個は不可 )。".+" の前と後にある文字に挟まれた、最長 の指定文字の列。= {1,} 。
. +?
".+" に該当する候補のうち、最短 の指定文字の列。
. {3 ,15 }
3 から15 個の指定文字からなる文字列の中で、前後の条件を満足する最長 の文字列。
. {3 ,15 }?
".{3,15}" に該当する候補のうち、最短 の指定文字の列。
. {3 ,}
3 個以上の指定文字からなる文字列の中で、前後の条件を満足する最長 の文字列。
. {3 ,}?
".{3,}" に該当する候補のうち、最短 の指定文字の列。
. ??
".?" に該当する候補のうち、最短の指定文字の列。 しかし、有用性が不明。原稿が "あいううえお" のとき、"/い.?う/" なら "いうう" に、"/い.??う/" なら "いう" にヒットする。ということは、.?? = ""(空文字) か?
記録呼び出し
\1
グループ化記録 された
1 番目の内容を呼び出す。グループ化のための開き括弧 "(" の出現順に、1番, 2番, 3番,... と数える(個数制限ほぼ無し。一説には99個なるも未確認)。
"
/( .) ( .) ( .) の逆さ言葉は\3\2\1 です/ " のとき、"
タヌキの逆さ言葉はキヌタです " や "
キツネの逆さ言葉はネツキです " にヒットする。
"
/\3\2\1の逆さ言葉は(.)(.)(.)です/ " は不可。グループ化の前に \1. \2, \3 などを置いても、空文字としてしか扱われない。また、存在しない記録番号や、評価がスキップされた記録番号の内容は "undefined" になる。
また、例えば、\1の直後に2という数字を続ける必要があるときは、\1(2)のように記述して、12番目の記録 \12 との混同を防ぐ。
\k<name >
名前つきグループ化記録 の呼び出し。名前を付けていても、上記の \番号 による呼び出しも有効。
非対応ブラウザ:Firefox, Edge, IE11 。
以下は、正規表現 $\boldsymbol{\mathcal{Regexp}}$ の中ではなく、replace コマンドと組み合わせて、置き換え用の文字列 $\boldsymbol{\mathcal{N\!ewstr}}$ の中で使用できる。
\$1
グループ化記録された
1 番目の内容を呼び出す。
\$1 , \$2, \$3, ...(個数制限ほぼ無し)。
グループ化記録の内容以外にも、次の情報の呼び出しが可能。
\$& : 検索結果の文字列。
\$` : \$& の前にある全原稿。
\$' : \$& の後にある全原稿。(
\$\$ : "\$"の文字そのまま)。
行末を表す "
\$ " とは無関係。また、
$\boldsymbol{\mathcal{N\!ewstr}}$ の中ではなく、コマンド実行後にJavaScriptから RegExp.\$1 のように呼び出すときにもこの記号が使われるが、似て非なるもの。
また、\$&, \$`, \$' は、コマンド実行後の RegExp による呼び出しには使用できないが、上記のように、
$\mathcal{N\!ewstr}$ の中では使用できる。
\$<name >
名前つきグループ化記録の呼び出し
非対応ブラウザ:Firefox, Edge, IE11 。
arguments[1 ]
グループ化記録された
1 番目の内容を呼び出す。replace コマンドの
$\mathcal{N\!ewstr}$ 部分を JavaScript の function に置き換え、例えば次のように記述。
function() {return
arguments[ 0
] .toUpperCase();} 。
各arguments番号は、
0 :検索結果の文字列、
n :n番目のグループ化記録、
n+1 :検索結果文字列の
index 、
n+2 :原稿全体。ただし、n = グループ化記録の全個数 = arguments.length - 3 。nの値の制限はほぼ無し。
オプション :
複数個のオプションの同時使用も可。これらの記述の順序は問わない。
g
最初に見つけた一つの該当文字列だけでなく、後続の該当文字列すべてを検索する。しかし、toString, search, split の各コマンドでは、このオプションの有無は結果には関係しない。
i
原稿内の半角英字を、大文字と小文字の区別をしないで検索。
m
"^" や
"\$" で行頭や行末を指示しても、m が無指定のときは、1行目の行頭や、最終行の改行無しの行末しか検索対象にしない。m を指定したときは、すべての行頭や行末が検索対象となる。
s
任意の一文字
"." に、改行文字
"\n" ,
"\r" も含める。非対応ブラウザ対策には、"." の代わりに"[.\n\r]" を使えばよい。
非対応ブラウザ:Firefox, Edge, IE11 。
u
4桁のUnicode(
\uhhhh )だけでなく、4桁以外のUnicode(
\u{hhhhh} など)や、
\p{sc= } 形式の曖昧表現の和文文字の認識も可能にする。
なお、このオプションを使うことで、通常は1文字が2文字とカウントされる
サロゲートペア文字 も、正しく1文字と認識されるようになると説明されることもあるが、実際にはそうはならない。
非対応ブラウザ:IE11 。
y
該当文字列が
$\mathcal{Regexp}$ .lastIndex で指示された位置から始まる場合にしかヒットさせない。その後、該当文字列が数珠つなぎで続くときは、つなぎが途絶えるまでのすべての文字列がヒットする。しかし、それ以降にある原稿の文字列は検索しない。利用例は
こちら 。
非対応ブラウザ:IE11 。
正規表現の応用例:
正規表現の機能は強力だが、簡易な利用だけでは目的を果たせないことも多い。その場合でも、複数回の処理・lastIndexの操作・functionの利用などで解決できることもある。
htmlエスケープ
HTML言語では、"<" や ">" のような文字は特殊な役割を持っており、そのままタイプしても画面には素直に表示されない。例えば、次のAのような文字列をタイプしても、画面上ではBのようにしか表示されない。
ホームページの画面に、タイプした通りの文字を表示するには、オリジナルの原稿の中にある特定の文字を、目に見える形式に変換しなければならない。
そのときに使われるのが「HTMLエスケープ」である。以下に、このために使用される JavaScript の function の例を3つ示す。
escape1()は、replaceコマンドを繰り返し使用する最も分かり易い変換方法である。escape2()は、escape1()との大きな違いはないが、毎回の処理結果を変数に再代入する操作を省略したものである。
一方、escape3()は
$\mathcal{N\!ewstr}$ 部分をfunctionに置き換えた別法である。前2者は全変換を終えるまでに原稿の走査を何回も必要とし、処理順序も"&"の変換を真っ先にしなければならないなどの問題があった。しかし、escape3()は走査が1回で済むので処理は早いし、変換テーブルの記述順序も問わないという利点がある。
なお、escape3()の方法は、arguments[]の個数が多いと記述が煩わしくなるが、次のような方法での対処もできる。すなわち、ここに示した例では空になっている function() の"( )"の中に、引数として適当な変数を function( a0, a1, a2. ... ) のように記入すれば、a0, a1, a2,... を arguments[0],[1].[2],... に代わるシンボルとして使用できるようになる。
検索漏れ対策
原稿
$\mathcal{Original}$ = "トウキョウトヤマナシマネ" には都府県名が5つも隠れているが、それらを拾い出すために
$\mathcal{Regexp}$ = /トウキョウ|キョウト|トヤマ|ヤマナシ|シマネ/g としても、
キョウト と
ヤマナシ にはヒットしない。なぜなら、何らかの文字列がヒットすると、次の検索はその文字列の右端から始まるためである。すべてを残さず検索するための処理例を以下に2つ示す。
例1は、複数の検索文字列の数だけコマンドを繰り返し、検索のすべての結果を配列 result に収容するシンプルな方法。例2は、lastIndex を一文字ずつ右に移動しながら、y オプションを利用して検索し、すべての結果を配列 final_result に収容する方法である。
// 例1:
var result=original.match(/トウキョウ/g);
result=[result,original.match(/キョウト/g)];
result=[result,original.match(/トヤマ/g)];
result=[result,original.match(/ヤマナシ/g)];
result=[result,original.match(/シマネ/g)];
// 例2:
var regexp=/トウキョウ|キョウト|トヤマ|ヤマナシ|シマネ/gy;
var final_result=[];
var n=0;
while(n < original.length) {
regexp.lastIndex=n;
var result=regexp.exec(original);
if(result!=null) {
final_result.push(result);
}
n++;
}
文字列処理一般:
正規表現と並行して使われることが多い文字列処理コマンドについて、概要のみ列記しておく。
str="abcdefg"; のとき
str.length ⇒ 7 (文字列の長さ)
str[0] ⇒ "a" (
位置 0の右側の文字)
str[1] ⇒ "b"
str[2] ⇒ "c"
$\smash{\vdots}$
str.charAt(0) ⇒ "a" (位置0の右側の文字)
str.charAt(1) ⇒ "b"
str.charAt(2) ⇒ "c"
$\smash{\vdots}$
str.slice(3,5) ⇒ "de" (位置3~5間)
str.substring(3,5) ⇒ "de" (位置3~5間)
str.substr(3,2) ⇒ "de" (位置3から2文字)
上記3件、第2引数省略時は最後尾まで
str.replace("d","X") ⇒ "abcXefg"
str.padStart(9,"*") ⇒ "**abcdefg"
非対応ブラウザ:IE11 。
str.padEnd(9,"*") ⇒ "abcdefg**"
非対応ブラウザ:IE11 。
str.repeat(2) ⇒ "abcdefgabcdefg"
非対応ブラウザ:IE11 。
str.toUpperCase() ⇒ "ABCDEFG"
str.toLowerCase() ⇒ "abcdefg"
str.startsWith("ab") ⇒ true (先頭の文字はabか?)
非対応ブラウザ:IE11 。
str.endsWith("fg") ⇒ true (末尾の文字はfgか?)
非対応ブラウザ:IE11 。
str.includes("cd") ⇒ true (位置問わず、有るか?)
非対応ブラウザ:IE11 。
str="abcdcdab"; のとき
str.indexOf("cd") ⇒ 2 (前から検索)
str.lastIndexOf("cd") ⇒ 4 (後から検索)
存在しないときは-1 。
上記2件、第2引数で検索開始位置も指定可能。
lastIndexの定義は正規表現とは異なるので注意。
(index, lastIndexとも、検索文字列の左端位置)
str=" abc "; のとき
str.trim() ⇒ "abc"
str.trimStart() ⇒ "abc "
非対応ブラウザ:Edge, IE11 。
str.trimEnd() ⇒ " abc"
非対応ブラウザ:Edge, IE11 。
str="ab,cd,efg"; のとき
str.split(",") ⇒ ["ab", "cd", "efg"]
str1="ab"; str2="cd"; str3="efg"; のとき
str1.concat(str2,str3) ⇒ "abcdefg"
str1 + str2 + str3 ⇒ "abcdefg"
str="aあ𠀋"; のとき
str.charCodeAt(0) ⇒ 97 (16進表記=0x61)
str.codePointAt(0) ⇒ 97
非対応ブラウザ:IE11 。
str.charCodeAt(1) ⇒ 12354 (=0x3042)
str.codePointAt(1) ⇒ 12354
非対応ブラウザ:IE11 。
str.charCodeAt(2) ⇒ 55360 (=0xd840)誤
str.codePointAt(2) ⇒ 131083 (=0x2000b)正
非対応ブラウザ:IE11 。
charCodeAtはサロゲートペア文字に非対応。
String.fromCharCode(97,12354,55360) ⇒ "aあ�"
String.fromCodePoint(97,12354,131083) ⇒ "aあ𠀋"
非対応ブラウザ:IE11 。
( )内は16進表記も可。
String.fromCharCodeはサロゲートペアに非対応。
str="255.998"; のとき
Number(str) ⇒ 255.998
parseFloat(str) ⇒ 255.998
str="ffff"; のとき
parseInt(str,16) ⇒ 65535 (基数指定)
num=255.998; のとき
String(num) ⇒ "255.998"
num.toString(16) ⇒ "ff.ff7ced91687"
(基数指定)
num.toString() ⇒ "255.998"
(無指定は10進)
num.toFixed(5) ⇒ "255.99800"
固定小数点表示(小数点以下の桁数指定)
num.toExponential(3) ⇒ "2.560e+2"
浮動小数点表示(小数点以下の桁数指定)
num.toPrecision(10) ⇒ "255.9980000"
固定or浮動小数点表示(有効桁数指定)
使い方
"使ってみる"を
入力サンプル:
1
2
3
4
5
6
7
8
X (消去)
$\mathcal{Regexp}$ (正規表現)
原稿と正規表現を入力後、検索ボタンをクリック。
赤 枠の欄:
原稿内のヒット部分の背景がピンク表示される。
青 枠の欄:
位置番号やグループ化された内容が表示される。
yオプション付きのときには、lastIndexの欄も表示されるので、検索開始位置を入力してから再検索する。
入力サンプル ボタン 1~8をクリック。
原稿や正規表現の文例が表示される。
そのまま使うか、編集の元データにする。
$\mathcal{Original}$ (原稿)
注
ここからキーボードで入力できる制御コードは、
Enterキーによる改行\nのみ 。
外部エディタによるテキストの貼り付けで、その他の制御コードの取り込みも可能。ただし、
改行\rは強制的に改行\nに書き変わる 。
$\moveleft0.4em{\raise0.6ex{\tiny\boxed{\scriptscriptstyle{\array{{\raise-0.5ex\smash{\scriptsize{\sf{L}}}\hspace{0.6em}}\\{\raise-0.5ex\hspace{0.6em}\smash{\scriptsize{\sf{F}}}}}}}}}\!\!$
$\moveleft0.4em{\raise0.6ex{\tiny\boxed{\scriptscriptstyle{\array{{\raise-0.5ex\smash{\scriptsize{\sf{C}}}\hspace{0.6em}}\\{\raise-0.5ex\hspace{0.6em}\smash{\scriptsize{\sf{R}}}}}}}}}\!\!$
$\moveleft0.4em{\raise0.6ex{\tiny\boxed{\scriptscriptstyle{\array{{\raise-0.5ex\smash{\scriptsize{\sf{H}}}\hspace{0.6em}}\\{\raise-0.5ex\hspace{0.6em}\smash{\scriptsize{\sf{T}}}}}}}}}\!\!$
$\moveleft0.4em{\raise0.6ex{\tiny\boxed{\scriptscriptstyle{\array{{\raise-0.5ex\smash{\scriptsize{\sf{F}}}\hspace{0.6em}}\\{\raise-0.5ex\hspace{0.6em}\smash{\scriptsize{\sf{F}}}}}}}}}\!\!$
$\moveleft0.4em{\raise0.6ex{\tiny\boxed{\scriptscriptstyle{\array{{\raise-0.5ex\smash{\scriptsize{\sf{V}}}\hspace{0.6em}}\\{\raise-0.5ex\hspace{0.6em}\smash{\scriptsize{\sf{T}}}}}}}}}\!\!$
$\moveleft0.4em{\raise0.6ex{\tiny\boxed{\scriptscriptstyle{\array{{\raise-0.5ex\smash{\scriptsize{\sf{B}}}\hspace{0.6em}}\\{\raise-0.5ex\hspace{0.6em}\smash{\scriptsize{\sf{S}}}}}}}}}\!\!$
$\moveleft0.4em{\raise0.6ex{\tiny\boxed{\scriptscriptstyle{\array{{\raise-0.5ex\smash{\scriptsize{\sf{BE}}}}\\{\raise-0.5ex\smash{\scriptsize{\sf{L}}}\hspace{0.6em}}}}}}}\!\!$
$\moveleft0.4em{\raise0.6ex{\tiny\boxed{\scriptscriptstyle{\array{{\raise-0.5ex\smash{\scriptsize{\sf{NU}}}}\\{\raise-0.5ex\smash{\scriptsize{\sf{L}}}\hspace{0.6em}}}}}}}\!\!$
© TsuboLabo 2019
当サイトの閲覧や記載内容から生じる如何なる問題も免責とさせていただきます。 リンクは歓迎ですが、ページ構成の変更によりリンク切れすることもあります。
改訂履歴
2019A:
初アップロード (2019-12-26)