正規表現で手を付けようとしましたが、諦めました。非常に面倒だからです。
正規表現を作る方針をこのページの HTML を例にしてみます。
このようなタグがありました。
lang
1<button title="クリップすると、知りたい質問を追いかけることができます。" class="btnUnderstandWant js-addClip mod-icn btnAddClip" value="1"
2 type="image" key="7140">クリップ</button>
というタグがありました。
正規表現を作る方針ですが、「タグ内の class 属性内の NG ワードを削除する」ので、まずタグを見つける正規表現を作ります。そしてその中で class 属性を見つけます。さらに class 属性の内容を抜き出します。
HTML ですから class 属性の位置はタグ内のどこでも任意に決められますのでそれまでの部分の属性名・属性値は飛ばさなきゃいけませんし、その部分には漢字を含めハイフン・コロン・セミコロン・ピリオドなどを含め色々な文字が含まれています。また class 属性の属性値を指定する文字はシングルクオートであったりダブルクオートであったりする可能性があります。そしてシングルクオートやダブルクオートがエスケープされていたりしたら、もう目も当てられません。
つまり、 HTML の自由度のせいで、正規表現が非常に面倒になります。そして、場合によっては上記の例のようにタグ途中で改行されていたりすることもあります。
結論としては「書けますが面倒」です。 nokogiri などの HTML/XML パーサを使ってください。
もちろん、前提条件がお示しのタグぐらい統一されていて簡略であれば簡単ですけどね。
(もしも、対象となるタグの前提条件が明確になっているならば、それに合わせた程度で書くこともできますので、ご連絡ください。ただし、結果として正規表現が面倒になりそうであれば、その旨ご返答します。)
nokogiri でのパース方法を追記します。
タグが一つだけであることを前提としています(修正すれば複数タグでも扱えますので、必要があればやってみてください)。
lang
1ng_words = %w[ngword-1 ngword-2]
2str = %[<div class="XXX ngword-1 ngword-2"></div>]
3
4elem = Nokogiri::HTML.parse(str).xpath('/html/body/*').first
5classes = elem[:class].split
6classes -= ng_words
7elem[:class] = classes.join(" ")
8tag = elem.to_html
9puts tag #=> <div class="XXX"></div>
NG ワードは配列に入れておきます。
タグは Nokogiri::HTML.parse
すると html タグと body タグにラップされるので、 xpath('/html/body/*')
メソッドでラップを剥がして目的とするタグのみを含むインスタンス elem を抜き出します(div タグに限らず、どのようなタグでも使えるように書いています)。
続いて class 属性値を抜き出して文字列そして配列にし、 NG ワードを取り除いてから文字列に戻し、再度 class 属性値に設定しています。
あとは to_html
メソッドで戻せばいいだけです。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/02/24 10:05
2015/02/24 13:56