niwacchi.log

niwacchiのログ。

正規表現

「//」…マッチ
「\d」…0〜9の数字1文字にマッチするパターン
「+」…〜の1回以上の繰り返し
「=~」…パターン結合演算子

$strが正規表現「/\d+/」にマッチするか否かを調べる場合、

if ( $str =~ /\d+/ )
{
  # 数字列が含まれている場合の処理
}

ここまでのまとめ。
$strが数字列を含むかどうか判断する。

$str =~ /\d+/

$strの数字列を全て'number'に置換する。

$str =~ s/\d+/number/g;

$strの英小文字を全て英大文字に置換する。

$str =~ tr/a-z/A-Z/;


次、特殊変数「$&」について。パターンマッチを行った直後の「$&」には、マッチした値が自動設定されている。

$str = "300yen";
if ( $str =~ /\d+/ )
{
  print "$& is the number.\n";
}

300 is ther number.

ただし、この値は次のパターンマッチを行った場合はその結果に書き換わる。後々使用したい場合は、変数に代入しておくこと。特殊変数は次のように使用すると、複数のマッチ結果を取り出すことができる。
※「$1」「$2」「$3」が特殊変数。

my $str = '168,57,37';
if ( $str =~ /(\d+),(\d+),(\d+)/ )
{
	my $height = $1;
	my $weight = $2;
	my $age = $3;
	
	print "\$height = $height\n";
	print "\$weight = $weight\n";
	print "\$age = $age\n";
}

$height = 168
$weight = 57
$age = 37

変数への代入部分は次のような書き方もOK。

my ( $height, $weight, $age ) = ( $1, $2, $3 );

コンマ区切って切り出すという考え方もある。

my ( $height, $weight, $age ) = split( /,/, $str );


次は、正規表現表記中のコメントについて。「/x」という修飾子をつけることで可能となる。

if ( $str =~
		/(					#1つ目の左括弧
			(					#2つ目の左括弧
				\d					#数字
				+					#の1個以上の繰り返し
			)					#$2に設定されるのはここまで
			(					#3つ目の左括弧
				[A-Za-z]			#英文字
				+					#の1個以上の繰り返し
			)					#$3に設定されるのはここまで
		)					#$1に設定されるのはここまで
		/x
	)


「1つの子音に2つの同じ母音が続く」文字列をマッチさせたい。zooとかteeとか。
子音 [bcdfghjklmnpqrstvwxyz]、母音 [aeiuo]とすると、

/[bcdfghjklmnpqrstvwxyz]([aeiuo])\1/

※特殊変数「\1」を使用する。これは、括弧でくくられた部分にマッチした文字列がセットされる。


次、デフォルト変数「$_」について。

$str =~ /^From:/

これは、$strが「From:」で始まる文字列であれば真。
$strは次のように省略することができる。

/^From:/

この場合は、デフォルト変数「$_」がパターンマッチの対象となる。
つまり、次の式と同じ意味になる。

$_ =~ /^From:/

デフォルト変数を使用しない場合と使用する場合の2パターンのコードは次のようになる。

# デフォルト変数を使用しない
while ( my $line = <STDIN> )
{
	if ( $line =~ /^From:/ )
	{
		print $line;
	}
}
# デフォルト変数を使用する
while ( <STDIN> )
{
	if ( /^From:/ )
	{
		print;
	}
}

デフォルト変数「$_」を使用した場合は、コードがシンプルになるが、かえって処理がわかりにくくなる場合もあるので、適切な使用を心がけること。


マッチさせる方法は、「//」以外にもある。次のように「m」を先頭につけて他の文字を使用する方法もある。

/http:\/\/d\.hatena\.ne\.jp\//
m#http://d\.hatena\.ne\.jp/#
m!http://d\.hatena\.ne\.jp/!
m[http://d\.hatena\.ne\.jp/]
m{http://d\.hatena\.ne\.jp/}

メタ文字「\Q」「\E」を使うと、その間に挟まれた部分は文字列そのものとして扱われるので、その間にあるメタ文字(.や/など)に\を付ける必要がない。

m|\Qhttp://d.hatena.ne.jp/\E|


置換について。「s/置換前/置換後/」

my $str = "My name is NiwaHirokazu."
$str =~ s/NiwaHirokazu/niwacchi/;
print $str;

My name is niwacchi.

演算子表記は「s///」。sはsubstituteの意味。

式を評価する修飾子に「/e」がある。置換と組み合わせて「s/置換前/置換後/e」とすると、置換後の部分をPerlの式として評価(evaluation)する。つまり、置換後の部分にPerlの関数がある場合に、関数による演算を行ってくれる。

my $str = "How I wonder what you are.\n";
$str =~ s/\w+/ucfirst($&)/eg;
print $str;

How I Wonder What You Are.


メタ文字「\b」について。単語の境界にマッチする。
例えば、「s/and/AND/g」は次のようになる。
I like candy. and you too. → I like cANDy. AND you too.

しかし、「s/\band\b/AND/g」としたときは次のようになる。
I like candy. and you too. → I like candy. AND you too.