akihiro kamijo: RegExp Archives

March 24, 2006

String と正規表現

String クラス (livedocs@lab) のいくつかのメソッドは正規表現と一緒に使うことができます。文字列の中から特定の表現を抜き出したり置き換えたりしたいときにはなかなか便利です。

では、早速具体的なメソッドを見ていきましょう。

split() メソッド

split() メソッドは引数に渡されたパターンを区切りとして文字列を分解します。結果は配列に格納されます。

vvar myStr:String = "Happy like a honeybee";
trace(myStr.split("a"));
// H,ppy like , honeybee が出力される

引数には正規表現も使えます。空白文字を区切りに指定してみます。

var myStr:String = "Happy like a honeybee";
var myPattern:RegExp = /\s+/;
trace(myStr.split(myPattern));
// Happy,like,a,honeybee が出力される

正規表現に括弧が含まれると括弧内に一致した箇所も出力に含まれます。先ほどの正規表現に括弧を足してみます。

var myStr:String = "Happy like a honeybee";
var myPattern:RegExp = /(\s+)/;
trace(myStr.split(myPattern));
// Happy, ,like, ,a, ,honeybee が出力される

オプションとして返す要素の最大数を指定できます。これは2つ目の引数に指定します。

var myStr:String = "Happy like a honeybee";
var myPattern:RegExp = /(\s+)/;
trace(myStr.split(myPattern, 3));
// Happy, ,like が出力される

select() メソッド

select() メソッドは引数のパターンに一致する箇所があればその先頭文字のインデックスを返します。見つからなかった場合は -1 を返します。パターンには String 型または RegExp 型のオブジェクトを使用できます。

var myStr:String = "Happy like a honeybee";
trace(myStr.search("li")); // 6 が出力される
 
var myPattern:RegExp = /(\w)\1/;
trace(myStr.search(myPattern)); // 2 が出力される

select() メソッドでは最初に見つかった箇所しか知ることができません。g フラグや lastIndex は無視されます。

ちなみに indexOf() メソッドと lastIndexOf() メソッドを使えば検索開始位置を指定できます。ただし、正規表現は使用できません。

var myStr:String = "Happy like a honeybee";
// 6 文字目から後ろへ検索する
trace(myStr.indexOf("a", 5)); // 11 が出力される
// 6 文字目から前へ検索する
trace(myStr.lastIndexOf("p", 5));; // 3 が出力される

lastIndexOf() はインデックス値を指定すると、指定された箇所から前に検索を行います。上の例では4文字目の p と先に一致するため返り値は 3 になっています。

match() メソッド

match() メソッドは引数のパターンに一致した箇所を配列として返します。パターンには文字列または正規表現を使用できます。

var myStr:String = "Happy like a honeybee";
var myPattern:RegExp = /(\w)\1/;
trace(myStr.match(myPattern)); // pp が出力される

上記のように正規表現に g フラグが無い場合最初に一致した箇所のみが返されますが、g フラグを付けると文字列全体を検索します。

var myStr:String = "Happy like a honeybee";
var myPattern:RegExp = /(\w)\1/g;
trace(myStr.match(myPattern)); // pp,ee が出力される

いずれの場合も lastIndex の値は使用されません。

replace() メソッド

replace() メソッドは1つ目の引数で指定されたパターンに一致した箇所を2つ目の引数を使って置き換えます。置き換え済の文字列が戻り値になります。

var myStr:String = "Happy like a honeybee";
var myPattern:RegExp = /(\w)\1/g;
trace(myStr.replace(myPattern, "xx")); 
// Haxxy like a honeybxx が出力される

パターンには文字列と正規表現が使えます。オリジナルの文字列は変更されません。

でも、これだといつも置き換えに使う文字列は同じものになってしまいますね。そのため、第2引数には関数を指定することもできるようになっています。関数は一致するごとに呼ばれ、最初の引数に一致した部分、最後から2番目の引数に一致した箇所の先頭のインデックス、最後の引数に元の文字列が渡されます。

var myStr:String = "Happy like a honeybee";
trace(myStr.replace("li", myFunc));
// Happy li6ke a honeybee が出力される
 
private function myFunc(...args):String {
  trace(args);
  // li,6,Happy like a honeybee が出力される
  return args[0] + args[1];
}

パターンに正規表現を使用した場合、正規表現が括弧を含むとそれぞれの括弧に一致した箇所も2つ目以降の引数として括弧の数だけ渡されます。

var myStr:String = "Happy like a honeybee";
var myPattern:RegExp = /(\w)\1/g;
trace(myStr.replace(myPattern, myFunc));
// Hapy like a honeybe が出力される
 
private function myFunc(...args):String {
  trace(args);
  // ee,e,19,Happy like a honeybee が出力される
  return args[1];
}

Posted by ackie at 05:18 PM | Comments (0)

March 23, 2006

AS3 と正規表現

AS3 では ECMAScript3 に定義されている正規表現が使用できます。これで文字列の操作もずいぶん便利になりました。おかげで前より普通にスクリプト言語らしくなった気がします。

RegExp クラス

正規表現は「数字だけから成る文字列」とか「<p> と </p> で囲まれた文字列」のようなパターンを記述するための表現です。ECMAScript3 の仕様では、先に挙げた2つの例であればそれぞれ \d+ と <p>.*</p> といった記述ができます。

これらの正規表現を AS3 で使用するには RegExp クラス (livedocs@lab) を使用します。対象となる具体的なパターンを / (スラッシュ)で挟むと RegExp のインスタンスの初期化ができます。

var myPattern1:RegExp = /\d+/;
var myPattern2:RegExp = /<p>.*</p>/g;

2行目の例ではパターンの後に g が付いています。このようにフラグを指定することも可能です。ちなみに g フラグは global の略で複数のマッチングをする際の指定になります。正規表現を使い慣れた人にはお馴染みですね。

オブジェクト指向好きならコンストラクタを使っても同様にインスタンスが生成できます。

var myPattern1:RegExp = new RegExp("\d+");
var myPattern2:RegExp = new RegExp("<p>.*</p>", "g");
 
trace(myPattern1.source); // \d+ が出力される

ちなみにインスタンスの持つパターンは source 属性から参照できます。この値は参照のみが可能です。

test() メソッド

RegExp クラスの test() メソッドは引数として渡された文字列に、あるパターンが含まれているかをチェックします。

var myStr:String = "0123456789";
var myPattern:RegExp = /12/;
var result:Boolean = myPattern.test(myStr);
trace(result); // true が出力される
trace(myPattern.lastIndex); // 3 が出力される

上の例では、myStr の2文字目と3文字目に myPattern (1と2の連続)が一致するため結果は true になっています。

また、結果が true のとき、lastIndex には一致した箇所の最後の文字のインデックス値が設定されます。

test() を呼ぶとき lastIndex 属性を使うとパターンマッチングを開始する文字を指定することができます。例えば lastIndex を 2 にすると最初の2文字はスキップされます。ただし、このとき正規表現に g フラグを設定する必要があります。

var myStr:String = "0123456789";
var myPattern:RegExp = /12/g;
myPattern.lastIndex = 2; var result:Boolean = myPattern.test(myStr); trace(result); // false が出力される

上の例は3文字目からチェックを開始するために結果が false になります。

exec() メソッド

exec() メソッドは引数の文字列内でパターンに一致した箇所の文字列を含むオブジェクトを返します。一致する箇所が無い場合の返り値は null です。

var myStr:String = "Happy like a honeybee";
// 小文字の a から z のみが連続するパターン
var myPattern:RegExp = /[a-z]+/;
var result:Object = myPattern.exec(myStr);
trace(result[0]); // appy が出力される
trace(result.index); // 1 が出力される
trace(result.input); // Happy like a honeybee が出力される

結果のオブジェクトには一致した文字列の他に、一致した箇所の先頭を示す index 属性と渡された文字列を保持する input 属性があります。

パターンが括弧を含む場合、結果のオブジェクトはそれぞれの括弧に一致した箇所も返します。配列の2番目以降のアイテムが括弧の登場する順番に一致した値になります。次の例では同じ文字が2回以上続くパターンを括弧を一つ使い指定しています。このため結果には (1) 一致した箇所全体と (2) 括弧の中と一致した部分が含まれます。

var myStr:String = "Happy like a honeybee";
var myPattern:RegExp = /(\w)\1/;
var result:Object = myPattern.exec(myStr);
trace(result[0]); // pp が出力される
trace(result[1]); // p が出力される - (\w) に一致した文字列
trace(result.index); // 2 が出力される
trace(result.input); // Happy like a honeybee が出力される

exec() メソッドも test() と同様に g フラグが設定されていれば lastIndex でマッチングを開始する箇所を指定できます。

var myStr:String = "Happy like a honeybee";
var myPattern:RegExp = /(\w)\1/g;
myPattern.lastIndex = 5; var result:Object = myPattern.exec(myStr); trace(result[0]); // ee が出力される trace(result.index); // 19 が出力される trace(result.input); // Happy like a honeybee が出力される

一致した文字列が見つかると lastIndex 属性に一致した箇所の最後の文字のインデックス値が設定されます。これも test() と一緒です。この仕様とループを組み合わせれば、文字列の最初から一つ一つ一致する箇所を探すこともできます。

var myStr:String = "Happy like a honeybee";
var myPattern:RegExp = /(\w)\1/g;
var result:Object = myPattern.exec(myStr);
while (result != null) {
  trace (result.index + ":" + result[0]);
  result = pattern.exec(str);
}
// 以下の2行が出力される
// 2:pp
// 19:ee

上のサンプルで g フラグを忘れると無限ループになります。間違えやすいので注意しましょう。

Posted by ackie at 06:20 PM | Comments (0)