2

BashスクリプトからPHPファイル(正確にはPHTMLファイルですが、それでも有効なPHPファイルです)にいくつかの変更を加える必要があります。私の当初の考えは、正規表現でsedまたは同様のユーティリティを使用することでしたが、他のHTML解析の質問についてここでいくつかの回答を読むと、より良い解決策があるようです。

正規表現で直面していた問題は、一致させたい文字列(src|href|action)=["']/<?php ?>タグ内にあるかどうかを検出するためのサポートがないことでした。そのため、一致がPHPタグ内にある場合は文字列の連結を実行するか、新しい文字列を追加することができました。 PHPタグはそうではないはずです。例えば:

(1) <img id="icon-loader-small" src="/css/images/loader-small.gif" style="vertical-align:middle; display:none;"/>
(2) <li><span class="name"><?php echo $this->loggedInAs()?></span> | <a href="/Login/logout">Logout</a></li>
(3) <?php echo ($watched_dir->getExistsFlag())?"":"<span class='ui-icon-alert'><img src='/css/images/warning-icon.png'></span>"?><span><?php echo $watched_dir->getDirectory();?></span></span><span class="ui-icon ui-icon-close"></span>
(EDIT: 4) <form method="post" action="/Preference/stream-setting" enctype="application/x-www-form-urlencoded" onsubmit="return confirm('<?php echo $this->confirm_pypo_restart_text ?>');">

(1)にはsrc="/css、があり、PHPタグにはないので、それをにしたいと思いますsrc="<?php echo $baseUrl?>/css。(2)にはPHPタグがありますが、の周りにないhref="/Loginので、にもなりhref="<?php echo $baseUrl?>/Loginます。残念ながら、(3)にはPHPタグsrc='/cssが含まています(エコーされた文字列です)。"これはPHPコードでも引用されているため、変更もそれを反映する必要があります。最終的な結果は次のようになりますsrc='".$baseUrl."/css

HTMLおよびPHPファイルに対する他のすべての変更は、正規表現を使用して行われました(私は知っています、私は知っています...)。正規表現が特定のパターンを除くすべてのマッチングをサポートできる場合、たとえば、[^(<\?php)(\?>)]*この部分を飛んでいきます。残念ながら、これはタイプ2の文法領域のようです。だから-私は何を使うべきですか?理想的には、GNUスイートとともにデフォルトでインストールする必要がありますが、PHP自体や他のインタープリターなどの他のツールも問題ありません。もちろん、誰かが上記の例で機能する正規表現を構築できれば、それは素晴らしいことです。

編集:(4)は厄介な一致であり、ほとんどの正規表現は失敗します。

4

1 に答える 1

3

この問題を解決する方法は、ファイルをでカプセル化されたセクションに分割することでした。スクリプトは、現在の「コンテキスト」を追跡していました。デフォルトではhtmlに設定されていますが、これらのタグにヒットするとphpに切り替わります。次に、操作(必ずしも正規表現である必要はありません)がそのセクションで実行され、出力バッファーに追加されます。ファイルが完全に処理されると、出力バッファがファイルに書き戻されます。

sedでこれを実行しようとしましたが、改行が印刷される場所を制御できないという問題に直面しました。コンテキストベースのロジックもハードコーディングされていたため、たとえばASP.NETサポートなどの新しいコンテキストを追加するのは面倒でした。私の現在のソリューションはPerlで書かれており、両方の問題を軽減します。ただし、正規表現で実際に何かを実行するのに少し問題がありますが、これは正規表現を正しくコーディングしていない可能性があります。

スクリプトは次のとおりです。

#!/usr/bin/perl -w

use strict;

#Prototypes
sub readFile(;\$);
sub writeFile($);

#Constants
my $file;
my $outputBuffer;
my $holdBuffer;
# Regexes should have s and g modifiers
# Pattern is in $_
my %contexts = (
    html => {
        operation => ''
    },
    php => {
        openTag => '<\?php |<\? ', closeTag => '\?>', operation => ''
    },
    js => {
        openTag => '<script>', closeTag => '<\/script>', operation => ''
    }
);
my $currentContext = 'html';
my $combinedOpenTags;

#Initialisation
unshift(@ARGV, '-') unless @ARGV;
foreach my $key (keys %contexts) {
    if($contexts{$key}{openTag}) {
        if($combinedOpenTags) {
            $combinedOpenTags .= "|".$contexts{$key}{openTag};
        } else {
            $combinedOpenTags = $contexts{$key}{openTag};
        }
    }
}

#Main loop
while(readFile($holdBuffer)) {
    $outputBuffer = '';
    while($holdBuffer) {
        $currentContext = "html";
        foreach my $key (keys %contexts) {
            if(!$contexts{$key}{openTag}) {
                next;
            }
            if($holdBuffer =~ /\A($contexts{$key}{openTag})/) {
                $currentContext = $key;
                last;
            }
        }
        if($currentContext eq "html") {
            $holdBuffer =~ s/\A(.*?)($combinedOpenTags|\z)/$2/s;
            $_ = $1;
        } else {
            $holdBuffer =~ s/\A(.*?$contexts{$currentContext}{closeTag}|\z)//s;
            $_ = $1;
        }
        eval($contexts{$currentContext}{operation});
        $outputBuffer .= $_;
    }
    writeFile($outputBuffer);
}

# readFile: read file into $_
sub readFile(;\$) {
    my $argref = @_ ? shift() : \$_;
    return 0 unless @ARGV;
    $file = shift(@ARGV);
    open(WORKFILE, "<$file") || die("$0: can't open $file for reading ($!)\n");
    local $/;
    $$argref = <WORKFILE>;
    close(WORKFILE);
    return 1;
}

# writeFile: write $_[0] to file
sub writeFile($) {
    open(WORKFILE, ">$file") || die("$0: can't open $file for writing ($!)\n");
    print WORKFILE $_[0];
    close(WORKFILE);
}

これを他の人が自分のニーズに合わせて使用​​および変更できることを願っています。

于 2012-11-02T18:06:21.347 に答える