プロが教える店舗&オフィスのセキュリティ対策術

javascriptを使って青空文庫のルビを削除したいと考えています。
例えば以下のような文章です。

「みんながうまそうに食べている<ruby><rb>最中</rb><rp>(</rp><rt>さなか</rt><rp>)</rp></ruby>に、こんな話は禁物だ。…

これを

「みんながうまそうに食べている最中に、こんな話は禁物だ。…

というようにしたいと思っています。
そこで、以下のようなコードを書いたのですが、どうもうまく動いてくれません。

-----------------------------------------------------------------------
doc = temp.replace(/<ruby><rb>(.+)<\/rb><rp>.+<\/rp><rt>.+<\/rt><rp>.+<\/rp><\/ruby>/gi, "$1");

処理結果:
「みんながうまそうに食べている最中</rb><rp>(</rp><rt>さなか</rt><rp>)</rp></ruby>に、こんな話は禁物だ。…
-----------------------------------------------------------------------

どこが誤っているのでしょうか?
ご指導お願いします。

A 回答 (5件)

正規表現で「.+」とすると任意の文字1文字以上となりますので(.+)に該当するのは


「最中・・・」から最後に出現するルビの部分になってしまいます。
「.+?」とすれば最小の文字列でマッチングする部分、となりますので
doc = temp.replace(/<ruby><rb>(.+?)<\/rb><rp>.+?<\/rp><rt>.+?<\/rt><rp>.+?<\/rp><\/ruby>/gi, "$1");
とすればうまくいくのではないかと思います。


おいしい最中(もなか)が食べたくなってきました・・・。
    • good
    • 0
この回答へのお礼

試してみたところ無事動きました。
ありがとうございました。
最中は好きです。

お礼日時:2010/12/18 13:40

おそらく質問文中と同じ論理構造とは限らないのですよね…。


もう少し簡単に考えてみてはどうでしょうか。

・rt要素, rp要素を子要素を含めて削除する
・ruby要素, rb要素を子要素を残して削除する

(※以下、全角空白は半角空白に置換してください)

---
<p>みんながうまそうに食べている<ruby><rb>最中</rb><rp>(</rp><rt>さなか</rt><rp>)</rp></ruby>に、こんな話は禁物だ。</p>
<p>みんながうまそうに食べている<ruby><rb>最中</rb><rt>さなか</rt></ruby>に、こんな話は禁物だ。</p>
<script type="text/javascript"><!--
(function () {

 function removeAllNodes (nodeList, deep) {
  var targetNode, parentNode, doc, df, childNodes, i, l, j;

  if (!nodeList) {
   return;
  }

  if (deep) {
   for (i = nodeList.length - 1; i > -1; i -= 1) {
    targetNode = nodeList[i];
    targetNode.parentNode.removeChild(targetNode);
   }
  } else {
   df = nodeList[0].ownerDocument.createDocumentFragment();

   for (i = nodeList.length - 1; i > -1; i -= 1) {
    targetNode = nodeList[i];
    parentNode = targetNode.parentNode;
    childNodes = targetNode.childNodes;
    j = childNodes.length - 1;
    if (j > -1) {
     for (;j > -1; j -= 1) {
      df.appendChild(childNodes[j]);
     }
     parentNode.replaceChild(df, targetNode);
    }
   }
  }
 }

 var doc = document;
 removeAllNodes(doc.getElementsByTagName('rt'), true);
 removeAllNodes(doc.getElementsByTagName('rp'), true);
 removeAllNodes(doc.getElementsByTagName('rb'), false);
 removeAllNodes(doc.getElementsByTagName('ruby'), false);
})();
//--></script>
---
    • good
    • 0
この回答へのお礼

勉強になりました。
ありがとうございました。

お礼日時:2010/12/18 13:40

ExtendScript Toolkit上では動きました



<が処理の段階ではエスケープされてて
&ltになってるとかじゃないでしょうか


でも#1の方のいわれてるように
最小一致にはしておいたほうがいいかと思います
    • good
    • 0
この回答へのお礼

エスケープが原因ではなかったみたいです。
ありがとうございました。

お礼日時:2010/12/18 13:41

#2 です。


以下、正規表現で実装するケースです。(#2 と考え方は同じ)

https://gist.github.com/743362 を取り込んで、

---
(function () {
 function AozoraBunko (string) {
  this.string = string + '';
  return this;
 }
 AozoraBunko.prototype.removeAllTags = function (tagName /*, deep*/) {
  this.string = removeAllTags (this.string, tagName, arguments[1]);
  return this;
 }

 var aozoraString, aozora;

 aozoraString = [
  'みんながうまそうに食べている\u003Cruby\u003E\u003Crb\u003E最中\u003C/rb\u003E\u003Crp\u003E(\u003C/rp\u003E\u003Crt\u003Eさなか\u003C/rt\u003E\u003Crp\u003E)\u003C/rp\u003E\u003C/ruby\u003Eに、こんな話は禁物だ。',
  'みんながうまそうに食べている\u003Cruby\u003E\u003Crb\u003E最中\u003C/rb\u003E\u003Crt\u003Eさなか\u003C/rt\u003E\u003C/ruby\u003Eに、こんな話は禁物だ。'
 ].join('\r\n');
 aozora = new AozoraBunko(aozoraString).removeAllTags('rt', true).removeAllTags('rp', true).removeAllTags('rb', false).removeAllTags('ruby', false);

 alert([aozoraString, aozora.string].join('\r\n\u3000\u2193\r\n'));
})();
---

# 全角空白は半角空白に置換してください。
    • good
    • 0

#2, 4 です。



https://gist.github.com/743362 を更新して function removeTagsAll を入れ子のタグにも対応してみました。
"<ruby><ruby>hogehoge</ruby></ruby>" のようなタグの対応関係を認識して "hogehoge" に置換してくれます。(ruby要素は入れ子にならない仕様のようですが、念のため)
関数名が「removeAllNodes → removeNodesAll」「removeAllTags → removeTagsAll」に変更されているので、#2, 4 のコードを利用する場合は適宜修正してください。

元々のフォーマットが XHTML に準拠しているならDOM操作。
そうでないなら、正規表現で置換するという選択肢もありかなと思います。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!