実行しながら覚える正規表現

  対象データは mixi の足あと



mixi やってれば、手に入るデータです。
できれば自分のデータでやってみましょう(そのほうが楽しいです)。

  
2006年07月22日 23:03 <a href="show_friend.pl?id=1234567">マカロニ</a><br>

2006年07月22日 22:57 <a href="show_friend.pl?id=9876543">ボス</a><br>

2006年07月22日 22:38 <a href="show_friend.pl?id=7777777">山さん</a><br>
  

パターンの指定にまず以下を指定してみて下さい

[^\n]+\n

まずはここから話が始まります



結果は「一行ごとにデータが取得」されたはずです。
ちなみに、この処理は PHP で以下のように書かれています
( 日本語処理を想定して、mb_string の正規表現関数を使い、preg_match_all 関数と同じ機能を実装しています )

<?
require_once( "./mwin.php" );

mb_language( "ja" );
mb_internal_encoding("EUC-JP");

foreach( $_POST as $Key => $Value ) {
	$_POST[$Key] = str_replace("\\\\", "\\", $Value );
	$_POST[$Key] = str_replace("\\'", "'", $_POST[$Key] );
	$_POST[$Key] = str_replace("\\\"", "\"", $_POST[$Key] );
}
$_GET = $_POST;
?>

<HTML>
<HEAD>
<META http-equiv="Content-type" content="text/html; charset=euc-jp">
<TITLE>PHP 雛形</TITLE>
<LINK rel="stylesheet" type="text/css" href="style.css">
<STYLE type="text/css">
</STYLE>
</HEAD>
<BODY id="body" style='background-color:white'>

<?

if ( trim( $_GET['text'] ) == '' ) {
	print "対象データを入力して下さい";
	exit();
}
if ( trim( $_GET['pattern'] ) == '' ) {
	print "パターンを入力して下さい";
	exit();
}

if ( substr( $_GET['text'], 0, 4 ) == 'http' ) {
	$ret = @file_get_contents( $_GET['text'] );
	if ( $ret !== FALSE ) {
		$enc = mb_detect_encoding($ret, "SJIS,UTF-8,EUC-JP");
		if ( $enc == 'SJIS' || $enc == 'UTF-8' ) {
			$ret = mb_convert_encoding ( $ret, "EUC-JP", $enc );
		}
		$_GET['text'] = $ret;
	}
}

mb_ereg_search_init( $_GET['text'], $_GET['pattern'], "i" );
while( TRUE === mb_ereg_search() ) {
	$work = mb_ereg_search_getregs();
	$ncnt = 0;
	foreach( $work as $Key => $Value ) {
		$Value = mb_ereg_replace( "&", "&amp;", $Value );
		$Value = mb_ereg_replace( "<", "&lt;", $Value );
		$matches[$ncnt][] = mb_ereg_replace( ">", "&gt;", $Value );
		$ncnt++;
	}
}

print "<pre>";
print "<span style='color:blue'>[0] は、マッチした全体の文字列を指す</span>\n";
print "<span style='color:blue'>それ以外は () によってマッチした部分文字列</span>\n";
print_r($matches);
print "</pre>";

?>

</BODY>
</HTML>





  [^\n]+\n の意味と範囲指定マッチング



1) \n は言わずと知れた改行文字を指します。
2) [ と ] は、文字の集合を表す時に使います。
3) [] の中の先頭に書かれた ^ は、指定された文字集合以外を指定した事になります。
4) + は、直前の文字が1個以上連続した文字列を意味します

つまり、改行以外の n 個の文字が改行で終わる文字列・・・という事になり、
通常のテキストデータにおける「一行」を指す事になります

で。

この指定の仕方が、実は「範囲指定マッチング」の基本的な指定方法となります。

開始文字 + 終了文字では無い文字の集合で構成された文字列 + 終了文字

では、HTML Aタグの開始タグと終了タグの間の文字列はどうなるでしょうか。

  
>[^<]+</a
  

しかし、このままでは間の名前の前後にタグが付いてきてしまうので、以下のようにしてみて下さい

  
>([^<]+)</a
  



この () で囲まれた中身が部分マッチングと呼ばれ、これを使って必要な文字列を取得します。
( 複数指定が可能です )


[xyz]文字セットを指定します。角かっこで囲まれた文字の中のいずれかに一致します。たとえば、'[abc]' は "plain" の 'a' と一致します。
[^xyz]除外する文字セットを指定します。角かっこで囲まれた文字以外の文字に一致します。たとえば、'[^abc]' は "plain" の 'p' と一致します。
[a-z]除外する文字の範囲を指定します。指定された範囲にある文字と一致します。たとえば、"[a-z]" は小文字の英字 "a" から "z" の範囲にある任意の文字と一致します。
[^a-z]否定の文字の範囲。指定範囲以外の文字と一致します。たとえば、"[^a-z]" は小文字の英字 "a" から "z" の範囲外にある



  複数の部分マッチングを使用して id と 名前を取得

  
<a href="show_friend.pl\?id=([\d]+)">([^<]+)</a
  

  
<a href="show_friend.pl は、その文字列そのものを指します。

\? は、? がワイルドカード文字列なので、\ でエスケープしています。

id= はその文字列そのもの

\d は、数字文字で [0-9]と同じ意味
  






  年月日を取得

  
([\d]+)年([\d]+)月([\d]+)日[\s]+([\d]+):([\d]+)\s
  

ここでは、空白文字の区切りを [\s]+ と表現しています。

空白は複数でもかまいません。
空白文字とは、タブや改行も含まれます( 実際は他にもある )

\s は 空白一文字で、\でエスケープされる特殊文字を複数指定する場合は [] が必要です

[\s]+ : 複数の空白文字列
\s : 一つの空白文字
.+ : 任意の改行以外の複数文字列
A+ : A が1文字以上連続する文字列







  あらためて特殊文字

^入力文字列の先頭と一致します。かっこの中で使用した場合は、かっこ内の文字セットを否定します。^ と一致させる場合は \^ と指定します。
$入力文字列の末尾と一致します。$ は '\n' または '\r' の直前にも一致します。$ と一致させる場合は \$ と指定します。
*直前のサブ式と 0 回以上一致します。* と一致させる場合は \* と指定します。
+直前のサブ式と 1 回以上一致します。+ と一致させる場合は \+ と指定します。
.改行文字 \n 以外の 1 文字と一致します。. と一致させる場合は \ と指定します。
?直前のサブ式と 0 回または 1 回一致します。? と一致させる場合は \? と指定します。
|A|B|C というようにいずれかと一致します。| と一致させる場合は \| と指定します。
\b単語の境界と一致します。単語の境界とは、単語とスペースとの間の位置のことです。たとえば、'er\b' は "never" の 'er' と一致しますが、"verb" の 'er' とは一致しません。
\B単語境界以外と一致します。たとえば、'er\B' は "verb" の 'er' と一致しますが、"never" の 'er' とは一致しません。
\cxx で指定した制御文字と一致します。たとえば、\cM は Control-M またはキャリッジ リターン文字と一致します。x の値は、A-Z または a-z の範囲内で指定します。それ以外を指定すると、リテラル文字 "c" と認識されます。
\d任意の 10 進文字と一致します。[0-9] と同じ意味になります。
\D10 進数字以外の任意の 1 文字と一致します。[^0-9] と同じ意味になります。
\fフォームフィード文字と一致します。\x0c および \cL と同じ意味になります。
\n改行文字と一致します。\x0a および \cJ と同じ意味になります。
\rキャリッジ リターン文字と一致します。\x0d および \cM と同じ意味になります。
\sスペース、タブ、フォームフィードなどの任意の空白文字と一致します。[?\f\n\r\t\v] と同じ意味になります。
\S空白文字以外の任意の文字と一致します。[^?\f\n\r\t\v] と同じ意味になります。
\tタブ文字と一致します。\x09 および \cI と同じ意味になります。
\v垂直タブ文字と一致します。\x0b および \cK と同じ意味になります。
\w単語に使用される任意の文字と一致します。アンダースコアも含まれます。'[A-Za-z0-9_]' と同じ意味になります。
\W単語に使用される文字以外の任意の文字と一致します。'[^A-Za-z0-9_]' と同じ意味になります。
\xnn に指定した 16 進数のエスケープ値と一致します。16 進数のエスケープ値は 2 桁である必要があります。たとえば、'\x41' は "A" と一致します。'\x041' は '\x04' および "1" と同じ意味になります。この表記により、正規表現で ASCII コードを使用できるようになります。

  
^2006

\S\s$

2?0

2006|"[^"]+"|id
  






  修飾子

*直前のサブ式と 0 回以上一致します。たとえば、'zo*' は "z" とも "zoo" とも一致します。* は {0,} と同じ意味になります。
+直前のサブ式と 1 回以上一致します。たとえば、"zo+" は "zo" や "zoo" とは一致しますが、"z" とは一致しません。+ は {1,} と同じ意味になります。
?直前のサブ式と 0 回または 1 回一致します。たとえば、'do(es)?' は "do" または "does" の"do" と一致します。? は {0,1} と同じ意味になります。
{n}n には 0 以上の整数を指定します。正確に n 回一致します。たとえば、'o{2}' は "Bob" の 'o' とは一致しませんが、"food" の 2 つの o とは一致します。
{n,}n には 0 以上の整数を指定します。少なくとも n 回一致します。たとえば、'o{2}' は "Bob" の 'o' とは一致しませんが、"foooood" のすべての o とは一致します。'o{1,}' は 'o+' と同じ意味になります。'o{0,}' は 'o*' と同じ意味になります。
{n,m}m および n には 0 以上の整数を指定します。n は m 以下です。n 〜 m 回一致します。たとえば、'o{1,3}' は "fooooood" の最初の 3 つの o と一致します。'o{0,1}' は 'o?' と同じ意味になります。カンマと数の間には、スペースを入れないでください。














   SQLの窓    create:2006/07/22  update:2018/02/23   管理者用(要ログイン)





フリーフォントツール

SQLの窓ツール

SQLの窓フリーソフト

写真素材

一般ツールリンク

SQLの窓

フリーソフト

JSライブラリ