0

私は約20年の間に開発された大規模なプロジェクトに取り組んでおり、それは大規模です。300ページ程度に変更を加える必要があり、実際には約2800ページが置き換えられます。これにより、実際の置換を行うためにVisualStudioの正規表現を使用したいと思うようになります。

これは、特定のコマンドに基づいてコードを「実行」し、HTMLテキストを出力するパーサーに渡される別のファイルタイプの疑似HTMLファイルにあります。私が使用している構文には、次のような呼び出しを含む通常のHTMLコードが含まれています。

<div id="outer-box" <__@BGCOLOR>>            //Basic call
<div id="outer-box" <__@BGCOLOR TOGGLE"1">>  //Call with toggle (only) parameter

今私がする必要があるのはそれを次のように変更することです:

<div id="outer-box" style="<__@BGCOLOR>">
<div id="outer-box" style="<__@BGCOLOR TOGGLE="1">">

しかし、ここに問題があります。一部のタグには、すでに次のように宣言されたstyle属性があります。

<div id="inner-box" style="border:1px" <__@BGCOLOR>>  //One possibility
<div id="inner-box" <__@BGCOLOR> style="border:1px">  //Another one

つまり、次のように変更する必要があります。

<div id="inner-box" style="<__@BGCOLOR>border:1px">

私は今数時間それと戦ってきました、そしてそれを正しくすることができないようです。また、1行に複数のHTML要素が含まれることもあれば、特定の要素に複数のパーサー呼び出し(BGCOLORとは異なるコマンドを使用)が含まれることもあることも付け加えておきます。

私がまだ修正していないすべてのインスタンスを見つけるためにこれまでに持っているのは、次のようなものです。

~(style=")\<__\@BGCOLOR{.@}\>



編集:明確にするために、これはVisual StudioのRegEx構文を使用しており、特にBGCOLORコマンドの呼び出しを探しています。上記の正規表現を使用すると、<__ @ BGCOLOR [TOGGLE = "1"]>の前に「style=」が付いていないすべてのケースを検索して、すでに修正されているアイテムを除外できます。

4

2 に答える 2

2

テキストについていくつかの単純化した仮定を立てることから始めます。これは、HTML を正規表現と一致させようとするときは常に必要ですが、この場合は主に正規表現を読みやすくするためです。正規表現は、基本構造を変更することなく、より複雑な基準を反映するように修正できます。

  • 要素と属性の名前は常にアルファベットです (つまり、VS の:w、またはと一致し[A-Za-z]+ます)。
  • 属性名の前には常にスペースやタブ ( :b+) が付きます。
  • 属性値は常に引用符 ( :q) で囲みます。
  • =属性名とその値の間にスペースはありません。

また、 で否定先読みを使用する方法にも注目して~(style):wください。「1 つまたは複数の文字 ( :w) ですが、単語を構成している場合はそうではありませんstyle」と表示されます。" が前に付いていない限り、否定的な後読み: "であるかのように使用しています。多くの人がその間違いを犯します。<__@BGCOLOR{.@}>style=

私は 4 段階のプロセスを提案します。

まず、特別なトークンを含む任意の要素を照合し、トークンがすべての属性の後にリストされるように並べ替えます。

  • 探す:{\<:w(:b+:w=:q)*}{:b+\<__\@BGCOLOR[^<>]*\>}{(:b+:w=:q)+}
  • 交換:\1\3\2

次に、属性がある場合は、それstyleがリストされている最後の属性であることを確認します (ただし、特別なトークンの前):

  • 探す:{\<:w(:b+~(style):w=:q)*}{:b+style=:q}{(:b+~(style):w=:q)+}{:b+\<__\@BGCOLOR[^<>]*\>}
  • 交換:\1\3\2\4

3 番目に、特別なトークンをstyle属性でラップします。

  • 探す:{\<__\@BGCOLOR[^<>]*\>}\>
  • 交換:style="\1">

最後に、2 つのstyle属性がある場合は、それらをマージします。

  • 探す:style="{[^"]+}":b+style="{\<[^<>]+\>}"
  • 交換:style="\1; \2"

このテキストから始めます:

<div <__@BGCOLOR> id="inner-box" style="border:1px">
<div foo="bar" id="inner-box" <__@BGCOLOR TOGGLE="1"> style="border:1px">
<div id="inner-box" bar="foo" <__@BGCOLOR>>
<div  id="inner-box" <__@BGCOLOR> style="border:1px">
<div id="inner-box" style="border:1px" <__@BGCOLOR TOGGLE="1">>
<div id="inner-box" <__@BGCOLOR> foo="bar">

...私はこれで終わります:

<div id="inner-box" style="border:1px; <__@BGCOLOR>">
<div foo="bar" id="inner-box" style="border:1px; <__@BGCOLOR TOGGLE="1">">
<div id="inner-box" bar="foo" style="<__@BGCOLOR>">
<div  id="inner-box" style="border:1px; <__@BGCOLOR>">
<div id="inner-box" style="border:1px; <__@BGCOLOR TOGGLE="1">">
<div id="inner-box" foo="bar" style="<__@BGCOLOR>">

Visual Studio は、ここでは大きなハンディキャップです。これは優れた IDE ですが、その正規表現のフレーバーは奇妙です。このようなことをたくさん行う場合は、EditPad ProPowerGrepなど、標準構文でフル機能の正規表現を使用するツールに切り替えることを強くお勧めします。

編集:私は最終的に (比較的) 賢明なことを行い、主に問題が正規表現で解決できるかどうかを調べるために、Perl のようなフレーバーで正規表現を作成しました。それは、たった 2 つのステップで済みました。

探す:

(
  <\w+\b
  (?:
    \s*
    (?:
      \w+="[^"]+"
    |
      <(?!__@BGCOLOR)[^<>]*>
    )
  )*
  \s*
)
(<__@BGCOLOR[^<>]*>)
(
  (?:
    \s*
    (?:
      \w+="[^"]+"
    |
      <[^<>]+>
    )
  )*
)

交換:

$1style="$2"$3

探す:

(
  <\w+\b
  (?:
    \s*
    (?:
      (?!style)\w+="[^"]+"
    |
      <[^<>]+>
    )
  )*
  \s*
)
style="([^"]+)"
(
  (?:
    \s*
    (?:
      (?!style)\w+="[^"]+"
    |
      <[^<>]+>
    )
  )*
)
\s*style="([^"]+)"

交換:

$1style="$2; $4"$3

次のステップは、それを Visual Studio の構文に変換することです (それが可能であれば) が、私は疲れすぎて今すぐ始めることはできません。;) そして、私が前に言ったように、あなたがこの種のことをたくさんやろうとしているなら、専用のパーサーを書くか、標準構文を使用するツールまたは言語に切り替えることを検討すべきです (非常に大まかな定義のために) "標準")。何をするにしても、Visual Studio のネイティブのいわゆる正規表現の使用をやめれば、すべての人に有利になります。:D

于 2012-07-03T04:21:39.343 に答える
0

これが私が思いついたものです(誰でも自由に編集できます):

正規表現:^.*<.*(<.*>(?!")).*>.*$

これで領域がキャプチャされ、<__@BGCOLOR>ニーズに合ったものに置き換えることができます。

于 2012-07-03T00:54:14.260 に答える