ヒアドキュメントの中ではタブを使ってはいけない

PHPではまったので、記載しておきます。

PHPXMLの処理についてPHP 開発者のための XML: 第 1 回 PHP での XML を 15 分で学ぶを参考に学習をしていたのですが、どうもヒアドキュメントを使用する箇所でパースエラーになり、うまくよみこめない。私の環境はOSX 10.5で、XAMPPもMAMPもローカルのApacheでも同様にパースエラーとなりました。 ヒアドキュメントができない。 - BIGLOBEなんでも相談室を見つけたので、文字コードと改行の問題かと思ったのですが、色々試しても解決しない。同様のエラーが出ていらっしゃる方がいたようでDo You PHP? - BBSに解決方法が記載されていました。

なぜこのようなパースエラーが生じていましたかというと、これは私が以下のように「Tab」を使用していたためです。

			$here_document = <<<EOD
			<tr><td>ヒア文字列</td><td>$greeting\n</td></tr>
			EOD;

「Tab」を使用することによって、何故か空白が出来てしまう。このように解釈されてしまう。これが原因だったようです。

ということのようです。私が参考にしていたPHP 開発者のための XML: 第 1 回 PHP での XML を 15 分で学ぶのソースをコピーするとヒアドキュメンとの箇所にtabが入っていたようです。

<?php 
  $xmlstr = <<<XML 
  <books> 
  <book> 
   <title>Great American Novel</title> 
   <characters> 
    <character> 
     <name>Cliff</name> 
     <desc>really great guy</desc> 
    </character> 
    <character> 
     <name>Lovely Woman</name> 
     <desc>matchless beauty</desc> 
    </character> 
    <character> 
     <name>Loyal Dog</name> 
     <desc>sleepy</desc> 
    </character> 
   </characters> 
   <plot> 
    Cliff meets Lovely Woman.  Loyal Dog sleeps, but wakes up to bark 
    at mailman. 
   </plot> 
   <success type="bestseller">4</success> 
   <success type="bookclubs">9</success> 
  </book> 
  </books> 
XML; 
 ?>


また、閉じタグの後ろに半角スペースが入っているのも、パースエラーになるようで、タブと半角スペースを削除して、次のように書き換えることで、無事にヒアドキュメンとが動作するようになりました。

<?php 
$xmlstr = <<<XML
<books>
<book>
<title>Great American Novel</title>
<characters>
<character>
<name>Cliff</name>
<desc>really great guy</desc>
</character>
<character>
<name>Lovely Woman</name>
<desc>matchless beauty</desc>
</character>
<character>
<name>Loyal Dog</name>
<desc>sleepy</desc>
</character>
</characters>
<plot>
Cliff meets Lovely Woman.  Loyal Dog sleeps, but wakes up to bark
at mailman.
</plot>
<success type="bestseller">4</success>
<success type="bookclubs">9</success>
</book>
</books>
XML;
?>

勉強にはなりましたが、こういう所で、はまるとつらいですね。

秀丸エディタで使用できない正規表現

秀丸エディタで使用できない正規表現があるようなので調べてみました。調査中なので追記していく予定です。(2008/10/13 16:45)

使用できない正規表現

種類 正規表現 意味 代替
文字の指定 \d 数字 [0-9]
\D 数字以外 [^0-9]
\s 空白文字 [\t\n\x0B\f\r]
\S 空白文字以外 [^\t\n\xOB\f\r]
\w 英数字とアンダースコア [a-zA-Z_0-9]
\W 英数字とアンダースコア以外 [a-zA-Z_0-9]
量の指定 *+ 独占的なマッチング(0個以上) 不明
++ 独占的なマッチング(1個以上) 不明
?+ 独占的なマッチング(0個または1個以上) 不明
{...}+ 独占的なマッチング(個数やその範囲を指定) 不明
位置の指定 \b〜\b 単語境界 \<〜\>
\A 入力の開始位置 不明
\Z 入力の終了位置 不明
\z 入力の終了位置 不明
\G 前にマッチした部分の直後 不明
$1,$2,$3… 補足グループ()でマッチした部分の文字列 \1,\2,\3…

調査に使用した秀丸エディタ

同じパターンの繰り返しを探す正規表現

(.+)\1{1,}
  • 「(.+)」で全ての文字列を補足グループに入れている
  • 「\1」で最初のマッチ(補足グループ)「()」と同じ
  • 「\1{1,}」で最初のマッチを1回以上の繰り返しを表す

「あああああ」「00」「あいうあいう」などがマッチする。

同じ数字が続く箇所を探す

([0-9])\1{1,}

「11」「222」「3333」などがマッチする。

特定の数字3文字が続く箇所を探す

([0-9]{3})\1{1,}

「123123123123」「444444」などがマッチする。

([0-9]{1,})-\1-\1

「123-123-123」にはマッチするが「123-456-789」にはマッチしない。

「○○○」の近くにある「△△△」を探す正規表現

後方参照(?<=)と、量指定{}を組み合わせる。

css」の1字以上100字以内にある「javascript」を探す場合は

(?<=css).{1,100}?javascript

とすればよい。ちなみに{1,100}後の「?」で控えめなマッチングを行っている。

後方参照を使わずに

css.{1,100}?javascript

でもよいかもしれない。

ただし、上記のどちらの方法でも「css」後の文字列から「javascript」までをすべて拾うので、改善の余地がある。(後方参照を使用した場合は「css」は含まない。)

このあたりと組み合わせられないだろうか?

文字列「○○○」以外に含まれている「○」を探す正規表現

「ABCDEFG」以外に含まれている「ABC」を探したい場合は

(?!=ABCDEFG)ABC

とすればよい。「ABCABCABCABC」の「ABC」は対象に含れるまれるが、「ABCDEFGHIJKLMNOPQRSTUVWXYZ」の「ABC」は対象に含まれない。

文字列「○○○」に含まれている「○」を探す正規表現

「ABCDEFG」の中に含まれている「ABC」を探したい場合は

(?=ABCDEFG)ABC

とすればよい。「ABCDEFGHIJKLMNOPQRSTUVWXYZ」の「ABC」は対象に含まれるが、「ABCABCABCABC」の中の「ABC」は対象に含まれない。

HTMLタグ〜内の文字列を探す正規表現

たとえば<span>〜</span>内の文字列を抜き出す場合は

(?<=<span*[^>]+>).+?(?=</span>)

とする。他のHTMLタグに利用する場合はspanの部分(2箇所)を変更すればよい。

HTMLタグ内に属性が記述されている場合(<span class="***">〜</span>)などにも対応している。