Google Sitesに登録されているドキュメントを、どうにかMarkdownに変換できないかと思ったのですが、
でも、WYSIWYGエディタで生成されたHTMLは結構怪しい構造になっており、
ツールによる変換を行うことができず、色々と加工する必要がありました。
その加工のうちの一つについて説明します。
正規表現で抜き出した部分のみを対象として、さらに正規表現で置換をかけた方法です。
言葉で説明するのが下手くそなので、見ていただいたほうが意味がわかるかもしれないです。
まずはこいつを見てほしい。
<div>
hoge<br>
fuga
<p>
piyo<br>
piyo
</p>
<p>
foo<br>
<br>
bar
</p>
</div>
すごく適当です。
今回説明するのは、上記のHTMLから、pタグの中のbrタグだけを削除する方法です。
(divタグ直下のbrは残す)
つまり、以下の結果を期待する、と。
<div>
hoge<br>
fuga
<p>
piyo
piyo
</p>
<p>
foo
bar
</p>
</div>
で、行った処理がこちら
const str = "<div>\n hoge<br>\n fuga\n <p>\n piyo<br>\n piyo\n </p>\n <p>\n foo<br>\n <br>\n bar\n </p>\n</div>"
const replaced = str.replace(/<p>(.*)<\/p>/sg, function(match){ return match.replace(/<br>/g, '') })
console.log(replaced);
まあ、String.prototype.replace()を当然利用するわけなんですが
replaceの第2引数には、関数を指定可能であると。
で、正規表現にグローバルフラグ /正規表現/g <- コレ
を付けていると、マッチした回数だけ、無名関数の第一引数 match
にマッチした部分文字列が入った状態で実行されるわけです。
示した例だと、pタグが2つあるので、2回実行されます。
var str2 = "<div>\n hoge<br>\n fuga\n <p>\n piyo<br>\n piyo\n </p>\n <p>\n foo<br>\n <br>\n bar\n </p>\n</div>"
var replaced2 = str.replace(/<p>(.*)<\/p>/sg, function(match){ console.log(match) })
//// 1回目の無名関数実行の第一引数matchのvalue
// <p>
// piyo<br>
// piyo
// </p>
//// 2回目の無名関数実行の第一引数matchのvalue
// <p>
// foo<br>
// <br>
// bar
// </p>
HTMLの場合なんかだと、タグ間の改行も考慮が必要なので、 sフラグ /正規表現/s <- これ
も付けます。
/<p>(.*)<\/p>/sg // <- つまり、sフラグとgフラグをつけてこうなる
この無名関数内で、returnした値が、matchした箇所と置換されることになります。
なので、matchに対して、再びプロトタイプのreplace関数を実行したものを returnすると
match.replace(/<br>/g, '') // brタグを削除する置換
意外と情報がなかったので備忘録として。
情報がなかったのは、正規表現を利用しないもっと良いやり方があるのかもしれない。。。