/ / Perlで失敗するWorking RegExがワンライナーを見つけて置き換える - regex、perl

Perlで失敗する正規表現を使用すると、1行の正規表現を見つけて置換する - regex、perl

私は以下の正規表現を持っています (<th>Password</th>s*<td>)w*(</td>) 一致する <th>Password</th><td>root</td> このHTMLでは:

<tr>
<th>Password</th>
<td>root</td>
</tr>

しかし、このTerminalコマンドは一致を見つけられません:

perl -pi -w -e "s/(<th>Password</th>s*<td>)w*(</td>)/$1NEWPASSWORD$2/g" file.html

それは、間の空白と関係があるようです。 </th> そして <td> しかし </th>s*<td> RegExで動作しますが、なぜPerlで動作しませんか。

代用してみた s* ために n*, r*, t* そしてそれらのさまざまな組み合わせが、まだ一致しません。

実用的な例が見られます ここに.

どんな助けでも感謝しています。

回答:

回答№1の場合は3

置換は、一度にファイルの1行にのみ適用されます。

ファイル全体を一度に読み込むことができます。 -0 このようなオプション

perl -w -0777 -pi -e "s/(<th>Password</th>s*<td>)w*(</td>)/$1NEWPASSWORD$2/g" file.html

それは 遠い 以下のような適切なHTMLパーサを使用することをお勧めします。 HTML::TreeBuilder::XPathこのようにデータを処理するには、正規表現を使用して特定のHTML構造のすべての可能な表現を説明することは非常に困難です。


回答№2については2

Perlはファイルを一度に1行ずつ評価します。たとえば、2行に渡って一致させようとしているので、perlは最初の行で探している文字列の終わりを見つけず、2番目の行で探している行の先頭を見つけません。

ファイルをフラット化することもできます。一時的に1行にHTML(ファイルのサイズやパフォーマンスがそれほど重要ではない場合にも有効です)または見つけた行を追跡するためにもっと洗練されたロジックを記述する必要があります。

"multiline regex perl"を検索してみてください。


答え№3の2

これを行うためにsedを使うことができます:

 sed -i "/<th>Password</th>/{n;s!<td>[^<]*!<td>NEWPASSWORD!}" file.html

別のsedのバージョン:

 sed -i "/<th>Password</th>/!b;n;s/<td>[^<]*/<td>NEWPASSWORD/" file.html