このディレクトリの索引
http://toro.2ch.net/test/read.cgi/tech/1323566370/745
#  ●正規表現の使用環境 
#  PCREライブラリを使用したアプリケーション 
#   
#  ●検索か置換か? 
#  置換 
#   
#  ●説明 
#  HTMLタグ形式で括られたテキストで#が二つ以上有るものを検索 
#  もし有れば対応する前方タグ内の後ろに@を付けたい 
#   
#  ●対象データ 
#  <AB><CD>nea##kv</CD>nk#eccu</AB> 
#  nea<YY><EF>###v</EF>orarcmm</YY> 
#  <HA>ne#<YY>#</YY>ec#cv</HA>axxzi 
#  <KK>#<CD>asiaev</CD>un##ima</KK> 
#   
#  ●希望する結果 
#  <AB><CD@>nea##kv</CD>nk#eccu</AB> 
#  nea<YY><EF@>###v</EF>orarcmm</YY> 
#  <HA>ne#<YY>#</YY>ec#cv</HA>axxzi 
#  <KK@>#<CD>asiaev</CD>un##ima</KK> 
#   
%
%  ここでは、
%  非決定性の処理を考える。先頭から順に置換が進んでいくように。
%  注意するべきことは、普通に非決定性に書くと、既に置換したつもりの
%  部分が変数の束縛が解かれて、置換前の状態にもどってしまうこと。
%  この型の述語では常にその点に注意する。
%

'HTMLタグ形式で括られたテキストで#が二つ以上有るものを検索もし有れば対応する前方タグ内の後ろに@を付けたい'(_文字列,_置換された文字列) :-
        タグとデータに分割する(_文字列,_タグとデータならび),
        '#が二つ以上有るものを検索もし有れば対応する前方タグ内の後ろに@を付けたい'(_タグとデータならび,_置換されたタグとデータならび),
        atomic_list_concat(_置換されたタグとデータならび,_置換された文字列).

タグとデータに分割する(_文字列,[_前データ,_タグ|R]) :-
        データとタグの切り取り(_文字列,_前データ,_タグ,_残り文字列),
        タグとデータに分割する(_残り文字列,R),!.
タグとデータに分割する(_文字列,[_文字列]).

データとタグの切り取り(_文字列,_前データ,_タグ,_残り文字列) :-
        sub_atom(_文字列,S1,1,_,'<'),
        sub_atom(_文字列,0,S1,_,_前データ),
        sub_atom(_文字列,S2,1,_,'>'),
        Len is S2 - S1 + 1,
        sub_atom(_文字列,S1,Len,R,_タグ),
        sub_atom(_文字列,S2_2,R,0,_残り文字列),!.


'#が二つ以上有るものを検索もし有れば対応する前方タグ内の後ろに@を付けたい'(L1,L2) :-
        append(L0,[A,B|R],L1).
        タグである(A),
        '#が二つ以上ある'(B),
        sub_atom(A,_,_,2,A_1),
        atomic_list_concat([A_1,'@>',B],C),
        append(L0,[C,B|R1],L2),
        '#が二つ以上有るものを検索もし有れば対応する前方タグ内の後ろに@を付けたい'(L0,A,B,C,R,L2).
'#が二つ以上有るものを検索もし有れば対応する前方タグ内の後ろに@を付けたい'([A|R1],[A|R2]) :-
        '#が二つ以上有るものを検索もし有れば対応する前方タグ内の後ろに@を付けたい'(R1,R2).
'#が二つ以上有るものを検索もし有れば対応する前方タグ内の後ろに@を付けたい'([],[]).

'#が二つ以上有るものを検索もし有れば対応する前方タグ内の後ろに@を付けたい'(L0,A,B,C,R1,L2).
        append(L0,[C|R1],L2).
'#が二つ以上有るものを検索もし有れば対応する前方タグ内の後ろに@を付けたい'(L0,A,B,C,R1,L2) :-
        '#が二つ以上有るものを検索もし有れば対応する前方タグ内の後ろに@を付けたい'(R1,L2_1),
        append(L0,[C,B|L2_1],L2).

タグである(A) :-
        sub_atom(A,0,1,_,<),
        sub_atom(A,_,1,0,>).

'#が二つ以上ある'(B) :-
        count(sub_atom(B,_,1,_,'#'),Count),
        Count >= 2.

%
%  count/2
%