難問?Perlの文字列置換について

このQ&Aのポイント
  • Perlの文字列置換について困っています。具体的には、以下のプログラムをベースにして置換を行いたいです。
  • 目標は以下のような置換結果になるようです。
  • しかし、どうしてもこの置換ができずに困っています。誰か教えていただけないでしょうか。
回答を見る
  • ベストアンサー

難問?Perlの文字列置換について

下記のプログラムをベースにして置換を行いたいです。 use File::Basename; use File::Copy; use File::Find; use File::Path; my @filelist = (); $inputfile='C:\Users\test.txt'; $outputfile='C:\Users\test_new.txt'; open (IN, $inputfile) or die "$!"; open (OUT, ">$outputfile") or die "$!"; while(<IN>) { $str = $_; if ($str =~ / ・・・・・ ・・・・・ } print OUT $str; } close (IN); close(OUT); sub wanted{ push(@filelist, $File::Find::dir."/$_") unless ($_ =~ /^\.$/); } Perlプログラムで下記の2つのソースを一括置換しようとしてます。 (1) paramIdとparamNameの文字列が同一の場合 <html:link styleClass="push" action="/numa.do" paramId="Id" paramName="Id" onclick="URL">ソース</html:link> (2) paramIdとparamNameの文字列が同一でない場合 <html:link styleClass="push" action="/numa.do" paramId="Id" paramName="Name" onclick="URL">ソース</html:link> やりたいことは ・ html:linkをs:aに変換 ・ styleClassをcssClassに変換(これはわかるのですが位置の修正がわかりません。。) ・ action="/numa.do"を/numaに変換 ・ paramIdとparamNameを文字列が同一か同一でないかで分岐処理したい。 目標は以下のように置換したいです。 (1) paramIdとparamNameの文字列が同一の場合 <s:a href="/numa?Id="%{ Id }" cssClass="push" onclick="URL">ソース</s:a> (2) paramIdとparamNameの文字列が同一でない場合 <s:a href="numa" paramId="Id" paramName="Name" cssClass="push" onclick="URL">ソース</s:a> どうしてもこの置換ができません、、誰かぜひ教えてください。 お願い致します。

  • Perl
  • 回答数3
  • ありがとう数6

質問者が選んだベストアンサー

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

えぇと, 実は「属性の順番に意味がある」方が (ある意味) 簡単だったりします. というのは, そのような場合には元のソース自体で ・styleClass → paramId → paramName → action という順に属性が表れる という仮定ができる可能性があるからです. もしそうなら難しくないですよね. これが, 「元のソースからして属性の順番がぐちゃぐちゃ」ということになると, わりとまじめに属性を処理する必要があります. まあできるんだけど, そういうことだと s でちまちま置換するよりも「元のソースから目的の文字列を『構築』する」という方針を考えた方が早いような気がする. 例えば $ref = "numa"; $paramId = "Id"; $paramName = "Name"; $class = "push"; $click = "URL"; $content = "ソース"; と変数に値があるときに <s:a href="numa" paramId="Id" paramName="Name" cssClass="push" onclick="URL">ソース</s:a> という文字列を作りたい (上の変数の値を href や paramId などの属性の値にする) としたら, どう作りますか?

その他の回答 (2)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

あ, 今気づいた. 「やりたいこと」の中に ・ action="/numa.do"を/numaに変換 ってあるんだけど, 「目標」の方にはこの属性が入ってない. そして, なぜか href なんて属性が増えてる. つまり「やりたいこと」が「目標」を正確には反映していない. あと #1 に補足: ・最終的に属性はどのような順番で並べればいいんでしょうか (「ほかの属性がある」場合には特に問題になるんだけど, そうでない場合も含めて)? ・元のソースで styleClass 属性の値が push でなかった場合にはどうすればいい? ・paramId, paramName および onclick の各属性の値は変わりえる?

numatahitomi
質問者

補足

・actionをhrefの属性に変更になります。 action="/numa.do"をhref="/numa"にしたいです。 ごめんなさい、属性の順番(位置)については考慮しなくてもよくなりましたので順番は特に問題ないです。 >・元のソースで styleClass 属性の値が push でなかった場合にはどうすればいい? その場合、属性の値は元の値と先の値を同じにさせます。 ・paramId, paramName および onclick の各属性の値は変わりえる? はい、変わります。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

まず, この手のことを本格的にやろうとしたら XML を扱うライブラリを使うことを考えるべきです. 例えば, 複数行にわたっていたりネストしていたりすると, 正規表現だけではなかなか難しいことをさせられる可能性があります. 逆に言えば, 「1行に収まっていて」「ネストはしていない」状況なら正規表現で処理することができます. ただし本題に入る前に以下の点を確認させてください: ・ほかの属性があったらどうしますか? ・「styleClassをcssClassに変換(これはわかるのですが位置の修正がわかりません。。)」とありますが, 「位置の修正」ってなんですか? そして, それはなぜしなければならないのですか (相手がよほどアホでない限り無意味な操作ですよ)? ついでに, 置き換えた結果を使う相手がよほどのアホであるという悲惨な状況を想定した場合, cssClass 属性はどこに入れる必要があるんですか? ・「action="/numa.do"を/numaに変換」とありますが, action 属性の値が "/numa.do" 以外のときは変換しないままでいいんですか? ・「paramIdとparamNameの文字列が同一の場合」のところに書いてある「%{ Id }」ってなんですか?

関連するQ&A

  • Perlの文字列置換について

    質問です。文字列の置換を行いたいのですが、まずはソースから・・・ use File::Basename; use File::Copy; use File::Find; use File::Path; my @filelist = (); $inputfile='C:\Users\test.txt'; $outputfile='C:\Users\test_new.txt'; open (IN, $inputfile) or die "$!"; open (OUT, ">$outputfile") or die "$!"; while(<IN>) { $str = $_; if ($str =~ /html:text/) { $str =~ s/html:text/s:textfield/g; $str =~ s/property/name/; $str =~ s/styleClass/cssClass/; elsif($str =~ /html:textarea/) { $str =~ s/html:textarea/s:textarea/g; $str =~ s/property/name/; $str =~ s/style/cssStyle/; $str =~ s/styleClass/cssClass/; } print OUT $str; } close (IN); close(OUT); sub wanted{ push(@filelist, $File::Find::dir."/$_") unless ($_ =~ /^\.$/); } Perlプログラムで下記のソースを一括置換します。 <html:text property="xxx" styleClass="yyy"> <html:textarea property="abc" styleClass="def" style="ghi"> 目標は以下のように置換したいです <s:textfield name="xxx" cssClass="yyy"> <s:textarea name="abc" cssClass="def" cssStyle="ghi"> しかし、上記のプログラムを実行すると <s:textfield name="xxx" cssClass="yyy"> <s:textfieldarea name="abc" cssClass="def" style="ghi"> となってしまいます。 どこをどう直せばよいのかわからないので誰か教えてください。 お願い致します!!

    • ベストアンサー
    • Perl
  • Perlの文字列置換について

    Perlで文字列置換の業務をすることになりした。 Struts1からStruts2のJSPのタグの変換です。 (1)html:textarea property="aaa" styleClass="bbb" (2)s:textarea name="aaa" cssClass="bbb" (1)から(2)に変換したいです。 「html:textarea」が「s:textarea」に対応しており、その属性の「property="aaa"」が「name="aaa"」に対応、 「styleClass="bbb"」が「cssClass="bbb"」に対応するといった内容です。 aaaとbbbは任意の文字列 if ($str =~ /html:textarea/ ) { $str =~ s/html:textarea/s:textarea/; $str =~ s/property=\"(.+)\"/name="$1"/; $str =~ s/styleClass=\(.+)"\"/cssClass/; というように参考書を元に作成してみたのですが、変換は行われるものの、属性のpropertyとstyleClassの順番が逆だったり、ここに記載していない他の属性を間に入れたりすると変換ができません。 どなたか教えて下さい。

    • ベストアンサー
    • Perl
  • perlを使った文字列のエンコードについて

    http://www.tagindex.com/tool/url.htmlにあるようなURLエンコードの処理を行いたいのですが、ソースはどのようになりますでしょうか? 下記のようなものできるのかと思いましたが、「テスト」の文字列ですと、「%83e%83X%83g」と表示されてほしいのが、「?e?X?g」となってしまいます。 お分かりの方がおられるようでしたら、ぜひ教えてください。 $str='テスト'; use Encode 'encode'; $str = encode('sjis', $str); print "$str";

    • ベストアンサー
    • Perl
  • 変数内のURL文字列を置換させたい

    変数に格納した文字列のうち、URLを以下のようにして 置換しようとしましたが、置換されませんでした。 $html = str_replace("www.sample.com/hoge", "hoge.hogeoge.net", $html); str_replace の使い方が間違っているのでしょうか。 どうぞ宜しくお願い申し上げます。

    • ベストアンサー
    • PHP
  • 文字列のアスタリスク置換

    PHP4でDBはMySQLを使用しています。 DBから取り出したいろいろな長さの文字列を*に置換したいのですがどのようにしたら良いでしょうか。 str_replaceを用いて置換をしようとしていますが文字列長が一定でないため難しいです。 宜しくお願い致します

    • ベストアンサー
    • PHP
  • 文字列の置換

    JAVAであるファイル内の文字列を置換するプログラム(日本語)を作りたいのですが、 ・ ・ String h_s; FileReader h_fr = new FileReader(in_filename); BufferedReader h_br = new BufferedReader(h_fr); while(true){  h_s = h_br.readLine();  if (h_s == null){   break;  }  ●文字列を置換するプログラム● } ・ ・ ここの●文字列を置換するプログラム●にあたる適当な関数って何かありますか? たとえばperlでいうと↓みたいなものなのですが・・・ s/置換前文字/置換後文字/g よろしくお願いします。

    • ベストアンサー
    • Java
  • Perlの文字列置換について

    とあるソースで $hogehoge =~ s!<文字列>! do{ $hoge =qq(hogehoge);} !egiox; $_ = $hoge; というのを見たのですが $hogehoge =~ s/<文字列>/hogehoeg/egiox;とは何が違うのでしょうか? また修飾子gとoではどちらが評価されるのでしょうか?または二つとも評価されるのでしょうか? 宜しくお願い致します。

    • ベストアンサー
    • Perl
  • 文字列置換

    PHPでの文字列置換についての質問です。 文字列を受け取った時には [09/06/04 21:01:05] といった値で受け取ります。これを [6月4日 21時1分] といった値で返そうと考えています。 str_replace、explodeでの方法も考えましたがあまりににくどい処理になるため、断念しました。 なにか他に手はないものでしょうか?? よろしければ回答お願いします。

    • 締切済み
    • PHP
  • PHPソースファイルの文字列置換をしてから、

    PHPソースファイルの文字列置換をしてから、 そのスクリプトを実行する方法を実行しようとしている のですが、うまくいきません。 似たような質問(http://oshiete.nikkeibp.co.jp/qa5496696.html) を参考にして、文字列置換自体はうまくいったのですが、 phpファイル実行時にまったく関係の無いはずの DBアクセスでエラーが発生してしまいました。 変換前前のphpファイルに置換後の文字列を手で入れて、 データベース実行するとうまくいきます。 しかしながら、phpファイルの文字列置換をstr_replaceで実行し、別名保存した後 includeしても、うまくいかないといった状況です。 ちなみに置換後のphpファイル内で $置換後文字列 = "test"; echo $置換前文字列; とすると、置換前文字列が置換後文字列に きちんと変わっているようで、 "test"と出力されます。 もしかすると、原因は違う所に潜んでいるのかもしれませんが、 どこを調べれば良いのか検討がつかず困っております。 どなたか解決手段の分かる方がいらっしゃれば教えて頂けませんでしょうか? -------------------------------------------------------------- 尚、ファイル構成は top |-change (1.php) |-database (2.php) |-search (検索画面[データベース検索の入り口。form action ="./3.php"],3.php) |-base (4.php,5.php[tempファイル]) となっており、 それぞれの中身は 1.文字列置換実行用のphpファイル(1.php):  1-1.file_get_contentsで4のphpファイルを取得  1-2.str_replaceを用いて文字列置換  1-3.文字列置換したファイルをfwriteで4.phpと同じディレクトリに保存(5.php)  1-4.5.phpをincludeする。  1-5.5.phpをunlinkする。 2.データベースアクセス(mysql)用関数を含むphpファイル(2.php):  ↓エラーの原因と思われる関数  function connect() { global $host,$user_id,$passwd,$con; $con = mysql_connect($host,$user_id,$passwd); } 置換前phpファイルを手動で文字列置換した場合には  同ファイル内で設定したglobal変数の値がきちんと格納されており、  データベース実行がうまくいきます。  置換後phpファイルでは$host等に値が格納されていないため、  データベース実行がうまくいきません。  グローバル変数の中身は同ファイル内で定義しています。 3.検索を実行した時に呼び出されるphpファイル(3.php):  3-1.include("../change/1.php"); 3-2.1.phpの関数の実行 4.文字列置換前のphpファイル(4.php): /*呼び出し元のディレクトリ位置でないとincludeに失敗する*/ 4-1.include("../database/2.php");  4-2.2.phpのデータベースアクセス関数を実行する。 5.文字列置換後のphpファイル(5.php): 3-2の1.php関数の実行により、一時的に生成される。

    • ベストアンサー
    • PHP
  • 文字列置換

    UNIXのコマンドで文字列の置換を試みています。 今回行いたい置換としては。。。 12年 1986年2月12日 14 などの文字列を NUM年 NUM年NUM月NUM日 NUM などに、連続した数字をひとまとめにNUMに置換したいと考えています。 文字列の置換方法としてsedコマンドがあると聞いてしらべてみたのですが、いまいいち理解することができませんでした。 自分で考えて試してみたコマンドが以下の通りです。 sed -e "s/\([1-9]\{1,2,3,4\}\)/NUM/g" filename が・・・まったく置換はされませんでした。 よろしければお教えください。よろしくお願いいたします。

専門家に質問してみよう