1

この質問はどこか(おそらくここ)で行われたと思いますが、情報が見つからなかったため、正確に説明する方法がわからないことが原因である可能性があります。

基本的に、私は高度な検索と置換を行うことを探しています。交換それに関しては私は理解できると確信していますが、今のところ私は発見を機能させることができません。

アプリケーションでは、ロードされているhtmファイルがたくさんあります。ユーザーはファイルを選択し、それを使用してアクションを実行します。このアクションが完了したら、システムでファイルをもう一度スキャンして、問題がないことを確認します。たとえば、この文字列はhtmファイルに存在する可能性があります。

<?strange_tag_start 
     name="var_value" ?>Name<?strange_tag_end ?>

そして、はい、それはこのような線を越えて壊れる可能性があります。これが起こらない限り、上記は問題ではありません:

<?strange_tag_start 
     name="var_value" ?><?strange_tag_start 
     name="var_value" ?>Name<?strange_tag_end ?><?strange_tag_end ?>

改行は異なる場合があります。私がやりたいのは、を含む文字列とを含む文字列をドキュメントで検索すること<?strange_tagです<?strange_tag_end ?><?strange_tag_startそれらが見つかったら、文字列内に別のものがあるかどうかを確認したいと思います<?strange_tag_end ?>

私は最初にファイルを読み取り、特定の値のすべてのインデックスを取得してから、それらを比較しようとしました。ただし、ファイルには次のものが含まれている可能性があり、これらは完全に問題ありませんが、システムがそれらを検出し、フラグを付けてくれます。

<?strange_tag_start 
     name="var_value" ?>Name<?strange_tag_end ?> There is other text here
and some more text on another line. Then this <?strange_tag_start name="var_value"
             ?>Name<?strange_tag_end ?> is present.

つまり、文字列の先頭を指定し、文字列の末尾を指定して、文字列が含まれているかどうかを確認するシステム(一部のアプリケーションに存在するものなど)です。

これが意味をなさない場合、またはさらに明確にする必要がある場合は、それを行うことができます。

アップデート

これで明確にしましょう。次の複数行の文字列があります。

I want to preserve<?start_foo  
                bar="value" ?> the content  
<?start_baz qux="value" ?>Name  
<?end-baz_qux ?>that is between weird tags.

見つけ<?start_foo bar="value" たい私も見つけたい<?end-baz_qux ?>(注:これらの2つが隣り合っている可能性があります)それらを見つけた後、その文字列内に別のものがあるかどうかを確認したい<?start_foo bar=(注:そのタグの「値」は同様に異なります。)次に、そこにあるとは思われない中間のコンテンツを削除したいので、最終的には次のようになります。

I want to preserve<?start_foo  
                bar="value" ?> the content 
<?end-baz_qux ?>that is between weird tags.

うまくいけばそれをより明確にするための別の例があります:

Back <?rh-udv_start name="ctrl_btn" ?><?rh-udv_start name="ctrl_btn" 
    ?>button<?rh-udv_end ?><?rh-udv_end ?> to

検索を行った後、私はこれで終わるはずです:

Back <?rh-udv_start name="ctrl_btn" ?>button<?rh-udv_end ?> to

基本的に、私は言う方法を探しています:

  1. VALUE_Xを使用して、「begins」(「begin」が文字列の途中にある可能性があるため誤解を招く)の文字列を検索します。
  2. 見つかった場合は、その後にVALUE_Yを見つけます(VALUE_Xがある場合は常にこれを見つける必要があります)。
  3. VALUE_Yの後で、別のVALUE_Yがあるかどうかを確認します。
  4. VALUE_XからVALUE_Yの文字列の内部をチェックして、別のVALUE_Xが含まれているかどうかを確認します。
  5. 別のVALUE_Xがある場合は、それを削除します。VALUE_Yの直後にVALUE_Yがある場合は、2番目のVALUE_Yを削除します。
4

2 に答える 2

2

私は信じている

<\?.*?\?>

ほとんどの正規表現フレーバー(Visual Studioを含む-どちらを使用しているかわからない)のタグを見つけるのに役立ちます。

奇妙なタグの間のコンテンツも置き換えたい場合は、より現実的な例を教えてください。正しい正規表現を提供するには、何を一致させようとしているのか(または非常に近い近似値)を正確に知ることが重要です。例えば

<?start_strange_tag blah="foo"?>Name<?end_strange_tag?>

とは大きく異なります

<?foo bar="baz"?>Name<?/foo?>

これはとは異なります

<?start_foo bar="baz"?>Name<?foo_end?>

等。

アップデート

以下のコメントに基づいて、次のようなドキュメントがあると想定します。

I want to preserve<?start_foo  
                    bar=\"value\" ?> the content  
<?start_baz qux=\"value\" ?>Name  
<?end-baz_qux ?>that is not between weird tags.

そして、結果を次のようにします。

I want to preserve the content  
that is not between weird tags.

また、(Visual Studioに組み込まれている正規表現ではなく).NET正規表現アセンブリを使用していることも前提としています。はい、それらは異なります。

その場合は、次のようなものを使用できます。

static void Main( string[] args )
{

    string l_input =
        "I want to preserve<?start_foo \n" + 
        "                    bar=\"value\" ?> the content\n" +
        "<?start_baz qux=\"value\" ?>Name\n" +
        "<?end-baz_qux ?>that is not between weird tags.";

    string[] l_singleTags = { "foo" };
    string[] l_multiTags = { "baz" };

    // Removing the single tags is easy:

    foreach ( var l_singleTag in l_singleTags )
        l_input = Regex.Replace( l_input, @"<\?start_" + Regex.Escape( l_singleTag ) + @"\b.*?\?>", "", RegexOptions.Singleline );

    // Removing the multi tags is not too bad:

    foreach ( var l_multiTag in l_multiTags )
        l_input = Regex.Replace( l_input, @"<\?start_" + Regex.Escape( l_multiTag ) + @" (?<param>\w+).*?\?>.*?<\?end-" + Regex.Escape( l_multiTag ) + @"_\k<param>.*?\?>", "", RegexOptions.Singleline );

    Console.WriteLine( l_input );

    Console.ReadKey( true );

}

l_inputになります:

I want to preserve the content  
that is not between weird tags.

更新2

質問の更新に応じて、次のコードを試してください。

static void Main( string[] args )
{

    string l_input =
        "Back <?rh-udv_start name=\"ctrl_btn\" ?><?rh-udv_start name=\"ctrl_btn\"" +
        "   ?>button<?rh-udv_end ?><?rh-udv_end ?> to";

    l_input = Regex.Replace( l_input, @"<\?(?<tagname>[-a-z]+_[a-z]+).*?\?>(?=<\?\k<tagname>)", "", RegexOptions.Singleline );

    Console.WriteLine( l_input );

    Console.ReadKey( true );

}

l_inputになります:

Back <?rh-udv_start name="ctrl_btn"   ?>button<?rh-udv_end ?> to

繰り返しタグを探して削除するだけです。例えば:

<?a_start foo="bar"?><?a_start    foo="bar"
?>

最初のタグが削除され、次のタグのみが残ります。

<?a_start    foo="bar"
?>

同様に終了タグを使用します。コードはタグ間のスペースやコンテンツを許容しません(その場合、どちらのタグも削除されません)。必要なものが得られるまで、この例を自由に使用してください。

于 2013-01-17T18:26:43.313 に答える
0

これには、 HtmlAgilityPackを使用できます。HTMLで引用を検索し、IDを序数に置き換えるなど、同様の目的で使用しました。私の場合、検索と置換は次のようになります。

var doc = new HtmlDocument();
doc.LoadHtml(html);
// find using xpath expression
var citeNodes = doc.DocumentNode.SelectNodes("//cite[@data-citationid]");
foreach (var node in citeNodes)
{
    // do some other stuff
    node.Name = "a";
    node.SetAttributeValue("id", "r" + citation.CitationId);
    node.InnerHtml = "[" + citation.Ordinal + "]";
}
return doc.DocumentNode.InnerHtml;
于 2013-01-17T18:30:00.677 に答える