S-JIS[2008-06-21/2009-09-24] 変更履歴

Ant:replace

ファイル内の文字列を置換するコアタスク。
(org.apache.tools.ant.taskdefs.Replace extends MatchingTask

最新replace


属性

属性 説明 備考
file="ファイル名" 置換対象ファイル。 どちらかは必須。(fileset要素は使えない)
dir="ディレクトリ名" 置換対象ファイル群の存在しているディレクトリー。
token="置換元文字列" 置換元文字列。 replacetokenやreplacefilterfileを使わない場合は必須。
value="置換先文字列" 置換後文字列。 省略すると空文字列に置換される。
replacefilterfile="ファイル名" 置換文字列を書いたファイル  
summary="on" 置換単語数と置換ファイル数を表示する。 具体的なファイル名まで出てくれると嬉しいんだけどなぁ。

単一の文字列を置換する例

	<replace dir="rep" token="sleep" value="zzz">
		<include name="**/*.html" />
		<exclude name="doc/**/*" />
	</replace>

dir属性で指定したrepというディレクトリーの下の拡張子htmlのファイル(ただしdocディレクトリー配下のファイルは除く)の中の「sleep」という単語を「zzz」に変える。


改行入りの文字列を置換する例

12345改行6789」という文字列を「9876改行54321」に置換する例。

	<replace dir="rep">
		<include name="**/*.html" />
		<exclude name="doc/**/*" />
		<replacetoken>12345
6789</replacetoken>
		<replacevalue>9876
54321</replacevalue>
	</replace>

replacetoken要素で置換元文字列を指定し、replacevalue要素で置換先文字列を指定する。

それぞれの要素のボディー部に書かれたものがそのまま文字列になる。つまりボディー部に改行やスペースを入れると、それも考慮の対象になる。
しかし、build.xml自体はXMLファイルなので、XMLの文法に従う。
すなわち、「<」「>」「&」はそのままでは書けない。「&lt;」「&gt;」「&amp;」といった実体参照を使う必要がある。

		<!-- <P>を<p>に置換する例 -->
		<replacetoken>&lt;P&gt;</replacetoken>
		<replacevalue>&lt;p&gt;</replacevalue>

逆に、文字参照(文字コード指定)を使うことも出来るので、改行は以下のように表現することも出来る。

		<replacetoken>12345&#x0d;&#x0a;6789</replacetoken>
		<replacevalue>9876&#x0d;&#x0a;54321</replacevalue>

※0d,0aは、MS-DOS(Windows)系テキストファイルの改行コード


Replaceタスクの説明には、CDATAセクションを使う方法が例として載っている。

		<replacetoken><![CDATA[two line
token]]></replacetoken>
		<replacevalue><![CDATA[two line
token]]></replacevalue>

しかしCDATAセクションは必ず使わなければならない、というものでは無い。 改行には全く無関係である。
上記の例は、以下と全く等価。

		<replacetoken>two line
token</replacetoken>
		<replacevalue>two line
token</replacevalue>


CDATAセクションは、ただ単に「<」や「>」等がそのまま書けるという、XMLの便利機能に過ぎない。

		<!-- <P>を<p>に置換する例 -->
		<replacetoken><![CDATA[<P>]]></replacetoken>
		<replacevalue><![CDATA[<p>]]></replacevalue>

CDATAセクション内には、<!-- -->を書くことが出来る。(XMLのコメント扱いにはならない)[2009-09-24]

		<!-- HTMLコメントをJSPコメントに置換する例 -->
	<replace dir="C:\temp">
		<include name="*.html" />
		<replacetoken><![CDATA[<!--]]></replacetoken>
		<replacevalue><![CDATA[<%--]]></replacevalue>
	</replace>
	<replace dir="C:\temp">
		<include name="*.html" />
		<replacetoken><![CDATA[-->]]></replacetoken>
		<replacevalue><![CDATA[--%>]]></replacevalue>
	</replace>

Eclipseでbuild.xmlを編集していてソースの整形機能を使うと、CDATAセクションの前後で改行されてしまう。

		<replacetoken>
			<![CDATA[<P>]]></replacetoken>
		<replacevalue>
			<![CDATA[<p>]]></replacevalue>

しかしreplacetokenやreplacevalueはその改行インデントの為のタブやスペースまで含めて置換文字列と判断するので、これは非常に困る。
CDATAセクションを使う場合は、ソースの整形は行わないようにするしか無いようだ。
Javaソースのソースの整形であれば、 改行の可否をけっこう細かく設定できるんだけどなー…。


複数の文字列を置換する例

置換したい文字列を複数指定するには、replacefilter要素を使う。

	<replace dir="rep">
		<include name="**/*.html" />
		<exclude name="doc/**/*" />
		<replacefilter token="&lt;P&gt;" value="&lt;p&gt;" />
		<replacefilter token="&lt;/P&gt;" value="&lt;/p&gt;" />
		<replacefilter token="&lt;P " value="&lt;p " />
	</replace>

replacefilter要素の子要素としてreplacetokenとreplacevalueが使えれば改行CDATAセクションが使えるのだが、残念ながらそういう設計にはなっていないようだ。
replacefilterで 改行付きの文字列を指定したいなら、文字参照を使って改行コードを指定するしか無い。


なお、replaceのボディー部に複数のreplacetokenとreplacevalueを指定した場合…

	<replace dir="rep">
		<include name="**/*.html" />
		<exclude name="doc/**/*" />
		<replacetoken>123</replacetoken>
		<replacevalue>abc</replacevalue>
		<replacetoken>456</replacetoken>
		<replacevalue>def</replacevalue>
	</replace>

replacetoken同士、replacevalue同士が結合されて、1つの置換文字列が指定されたことになってしまう。
すなわち上記の例だと、「123456」を「abcdef」に置換する、という指定になる。


プロパティーファイルによって置換文字列を指定する例

置換前後の文字列をプロパティーファイルによって指定することが出来る。

	<replace dir="rep" replacefilterfile="replace.properties">
		<include name="**/*.html" />
		<exclude name="doc/**/*" />
	</replace>

replace.properties

sleep=zzz
12345\u000d\u000a6789=9876\u000d\u000a54321
<P>=<p>
</P>=</p>
<P\u0020=<p\u0020

プロパティーファイル内では、「<」や「>」はそのまま使える。
改行コードは「\u000d\u000a」で表す。ちなみに「\u0020」はスペース。


Ant目次へ戻る / 技術メモへ戻る / テキスト置換ツールへ戻る
メールの送信先:ひしだま