ダブルクォーテーションの正規表現

解決


marllbolo  2012-06-20 11:26:41  No: 143347  IP: 192.*.*.*

いつも掲示板を使わせていただいています。VB2010を使っているのですが、
今、正規表現で立ち止まっています。

<TD align=right bgcolor="#202020">
<TD align=right bgcolor=#202020>
<TD bgcolor="#202020" align=right>
<TD bgcolor=#202020 align=right>

の4つをマッチさせたいのですが、
まず、1点目にダブルクォーテーションをエスケープする際、いろいろなサイトを見ましたが、
<TD align=right bgcolor=""#202020"">
であったり、
<TD align=right bgcolor=\"#202020\">
のような書き方をしているサイトを見かけました。正規表現のエスケープは"\"をつけると思っていたのですが、構文エラーが返ってきます。
また、<TD align=right bgcolor=""#202020"">で書いてもマッチさせてもらえず。どのように書いていいのやらわかりません。

2点目に、上記4つのいずれかをマッチさせるには、
(<TD align=right bgcolor="#202020">|<TD align=right bgcolor=#202020>|<TD bgcolor="#202020" align=right>|<TD bgcolor=#202020 align=right>)
でいいでしょうか。

宜しくお願いします。

編集 削除
marllbolo  2012-06-20 12:11:50  No: 143348  IP: 192.*.*.*

上記補足です。

<TD align=right bgcolor="#202020">
<TD align=right bgcolor=#202020>
<TD bgcolor="#202020" align=right>
<TD bgcolor=#202020 align=right>

はウェブサイトからInnerHTMLで取得して変数の中に格納してあります。

自分でダブルクォーテーションのテスト行うとき

Dim a as string = "<TD align=right bgcolor=""#202020"">"

のように書かないとテストできないのでやってはいるのですが、
結局、
Regex("<TD align=right bgcolor=""#202020"">",System.Text.RegularExpressions.RegexOptions.Singleline)

でマッチングしても意味がないのです。

編集 削除
YuO  2012-06-20 15:30:20  No: 143349  IP: 192.*.*.*

「正規表現として」文字をエスケープしないといけないのは,以下の文字です。
.$^{[(|)*+?\

この,「正規表現として」文字をエスケープする,というのは,文字の前に\を置くことに他なりません。

ref) 文字のエスケープ
http://msdn.microsoft.com/ja-jp/library/4edbef7e.aspx


次に,「VB言語として」「文字列リテラル中に」"を含めたい場合には""と書く必要があります。
これは,コンパイラが""を"に置き換えて処理してくれます。


> (<TD align=right bgcolor="#202020">|<TD align=right bgcolor=#202020>|<TD bgcolor="#202020" align=right>|<TD bgcolor=#202020 align=right>)
正規表現はこれで正しいですが,文字列リテラルにする場合は"→""の置き換えが必要です。
# キャプチャである程度は短くなりますが……。

編集 削除
marllbolo  2012-06-20 17:51:22  No: 143350  IP: 192.*.*.*

>「正規表現として」文字をエスケープしないといけないのは,以下の文字です。
>.$^{[(|)*+?\

なるほど、ダブルクォーテーションは入っていなかったんですね。
面目ないです。

># キャプチャである程度は短くなりますが……。

ぜひご教授下さい。自分にとってかなりの核心な部分です。

編集 削除
YuO  2012-06-20 22:46:36  No: 143351  IP: 192.*.*.*

>># キャプチャである程度は短くなりますが……。
> ぜひご教授下さい。自分にとってかなりの核心な部分です。

二重引用符の有無だけの違いで,判定対象が倍になっていますよね。
それをまとめる方法になります。

まず,
> <TD align=right bgcolor="#202020">

> <TD align=right bgcolor=#202020>
から。

・キャプチャ
ref) グループ化構成体 http://msdn.microsoft.com/ja-jp/library/bs2twtah
・前方参照
ref) 前方参照構成体 http://msdn.microsoft.com/ja-jp/library/thwdfzxy

まず,単純に"の有無だけを無視する正規表現を書きます。
<TD align=right bgcolor="?#202020"?>
たぶん,これはわかると思います。

しかし,これでは,
<TD align=right bgcolor="#202020>

<TD align=right bgcolor=#202020">
を許容してしまいます。#202020の前と後ろの二重引用符は「ある」か「ない」かです。

この時,#202020の前後には
・両方とも空文字列がある
・両方とも二重引用符がある
のどちらかとみなすことができますので,これをキャプチャと前方参照を使って表現します。
<TD align=right bgcolor=("?)#202020\1>
この()がキャプチャで,\1は「先頭から1番目の開き括弧のキャプチャと同じ文字列」を意味します。
この時,0番目のキャプチャはマッチした全文を意味するため,最初の(の場所は\1になります。

もう一方も同じですから,
> (<TD align=right bgcolor="#202020">|<TD align=right bgcolor=#202020>|<TD bgcolor="#202020" align=right>|<TD bgcolor=#202020 align=right>)
は,
(<TD align=right bgcolor=("?)#202020\2>|<TD bgcolor=("?)#202020\3 align=right>)
となります。
キャプチャは置換でも使える ($0, $1, ...) ので,覚えておくとよいかと思います。


なお,(?<aaa>などと名前を付けて,\{aaa}や${aaa}と参照する方法もあります。
Groupsプロパティで使うキャプチャには,名前を付けた方がわかりやすいでしょう。

編集 削除
marllbolo  2012-06-21 09:57:14  No: 143352  IP: 192.*.*.*

なんという短くきれいな正規表現でしょう。

期待以上の回答ありがとうございます。

><TD align=right bgcolor="#202020>
>や
><TD align=right bgcolor=#202020">

なるほどありえます。キャプチャだといわゆる同一のコピーですから、マッチの間違えはないですね。

編集 削除