teratail header banner
teratail header banner
質問するログイン新規登録

質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.30%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

3回答

2082閲覧

自動でふりがな付きのHTML文字列を作成するライブラリはないでしょうか

yutampp

総合スコア182

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2023/06/29 03:44

編集2023/07/04 09:08

0

1

入力例1

javascript

1const a = "お疲れ様です。"; 2const b = "おつかれさまです。";

入力例2

javascript

1const a = "試される大地北海道"; 2const b = "ためされるだいちほっかいどう";

という、a:漢字交じり文章、b:全部ひらがな文章
があったときに、
二つの文章の差分をとって、自動でふりがな付きのHTML文字列を作成するライブラリはないでしょうか。
あったら教えてください。
jsdiffという差分検出のライブラリは見つけたのですが、自動ふりがなまで自動でやってくれるライブラリくらい誰かが先に作っているのではないかと。
期待する出力1

html

1<p><ruby><rt>つか</rt></ruby><ruby><rt>さま</rt></ruby>です。</p>

期待する出力2

html

1<p><ruby><rt>ため</rt></ruby>される<ruby>大地北海道<rt>だいちほっかいどう</rt></ruby></p>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SLEEPY_EUTYCHUS

2023/07/04 07:06

期待する出力の1と2それぞれで最初のruby要素の終了タグが開始タグになっていますよ。
yutampp

2023/07/04 09:08

修正しました
guest

回答3

0

ベストアンサー

面白そうなので、正規表現の置換だけでどの程度出来るかやってみました。
この手のプログラムはRubyが一番書くのが楽そうなのでRubyで。

Ruby

1def ruby(kanji, kana) 2 regexp = Regexp.new(("^("+kanji.gsub(/[^ぁ-ん]+/,")(.+?)(")+")$").gsub("()","")) 3 kanji_split = kanji.split(/(?<=[ぁ-ん])(?=[^ぁ-ん])|(?<=[^ぁ-ん])(?=[ぁ-ん])/) 4 kana_split = regexp.match(kana)[1..] 5 kanji_split.zip(kana_split).map do |x,y| 6 x == y ? x : "<ruby>#{x}<rt>#{y}</rt></ruby>" 7 end.join 8end 9puts ruby("お疲れ様です。", "おつかれさまです。") 10puts ruby("試される大地北海道", "ためされるだいちほっかいどう") 11puts ruby("中々な金物","なかなかなかなもの") 12puts ruby("李も桃も桃のうち", "すもももももももものうち")

kanji_splitの所はもうちょっと上手く書きたいけど、あまり考えるとJavaScriptに書き直すときに困るので。

アウトプットは、

text

1お<ruby>疲<rt>つか</rt></ruby>れ<ruby>様<rt>さま</rt></ruby>です。 2<ruby>試<rt>ため</rt></ruby>される<ruby>大地北海道<rt>だいちほっかいどう</rt></ruby> 3<ruby>中々<rt>なか</rt></ruby>な<ruby>金物<rt>かなかなもの</rt></ruby> 4<ruby>李<rt>す</rt></ruby>も<ruby>桃<rt>も</rt></ruby>も<ruby>桃<rt>ももももも</rt></ruby>のうち

で、普通のパターンはOKですが、ややこしいのは駄目ですね。
直感的には一般の文章だと9割くらいは大丈夫な気がしますが、残りは手作業。
これが99%位なら、手作業無しで公開して指摘があったらそこだけ対応という手抜きも出来ますが。

これ以上精度を上げるためには、正規表現メソッドを使わず、自分で複数パターン検出して、
案1:人間がその中の1つを選択する
案2:何らかの評価関数でスコアを付けて最も高い物を選ぶ
案3:Chat-GPTに選んでもらう

案2だと、日本語解析データが必要そうで大変。自動化するなら今なら案3でしょうか。さらにそれを人間がチェックするか、手抜きでそのまま公開するか。

JavaScript版はzip相当が無いのでそこだけちょっとダサい。

JavaScript

1function ruby(kanji, kana) { 2 const regexp = new RegExp(("^(" + kanji.replace(/[^ぁ-ん]+/g, ")(.+?)(") + ")$").replace(/\(\)/g, "")); 3 const kanji_split = kanji.split(/(?<=[ぁ-ん])(?=[^ぁ-ん])|(?<=[^ぁ-ん])(?=[ぁ-ん])/); 4 const kana_split = kana.match(regexp).slice(1); 5 return kanji_split.map((x, i) => { 6 const y = kana_split[i]; 7 return x === y ? x : `<ruby>${x}<rt>${y}</rt></ruby>`; 8 }).join(""); 9} 10console.log( ruby("お疲れ様です。", "おつかれさまです。") ) 11console.log( ruby("試される大地北海道", "ためされるだいちほっかいどう") ) 12console.log( ruby("中々な金物","なかなかなかなもの") ) 13console.log( ruby("李も桃も桃のうち", "すもももももももものうち") )

投稿2023/06/29 15:15

編集2023/06/29 15:29
otn

総合スコア86341

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yutampp

2023/07/03 01:39 編集

ありがとうございます。正規表現でもできるんですね。 diff_match_patchを使ってrubyタグをつける部分は結局自力コーディングしました。 これ以上の精度を求めると、DeepLearningするかAI使うかになりますよね。 形態素解析ライブラリ使うのが楽そうですが、やっぱりしんどいので手抜きします。
guest

0

ChatGPTにより生成された文章です

正しくはChatGPTにより生成された文章を含んでいます。

以下本文

たとえば、

中々な金物
なかなかなかなもの

みたいなのを差分アルゴリズムだけでどうこうできるものなのかな……という疑問を持ちました。
形態素解析やふりがなAPIを使うぐらいではないと難しいのでは。

とりあえず、ChatGPTに聞いてみました。


以下の例のように、かな漢字混じり文とそのふりがなが入力で与えられた時に、HTMLのrubyタグでふりがなをコーディングしたいです。

例1:
かな漢字混じり入力が"お疲れ様です。"
ふりがな入力が"おつかれさまです。"
この場合の出力が"<p><ruby><rt>つか</rt><ruby><ruby><rt>さま</rt></ruby>です。</p>"

例2:
かな漢字混じり入力が"試される大地北海道"
ふりがな入力が"ためされるだいちほっかいどう"
この場合の出力が"<p><ruby><rt>ため</rt><ruby>される<ruby>大地北海道<rt>だいちほっかいどう</rt></ruby></p>"

以下の入力の場合はどのような出力になりますか?

かな漢字混じり入力が"中々な金物"
ふりがな入力が"なかなかなかなもの"


入力されたかな漢字混じり文とふりがなに基づいて、HTMLのrubyタグを使ってふりがなをコーディングすると、以下のような出力になります。

入力:
かな漢字混じり入力: "中々な金物"
ふりがな入力: "なかなかなかなもの"

出力:

html

1<p><ruby>中々<rt>なかなか</rt></ruby><ruby>金物<rt>かなもの</rt></ruby></p>

この出力では、漢字の部分が<ruby>タグで囲まれ、ふりがなが<rt>タグで指定されています。それぞれのふりがなが対応する漢字にマッピングされています。


ありがとうございます。たとえば、この処理を JavaScript のコードで書くとすると、どのようなコードになりますか?


JavaScriptを使用して、与えられたかな漢字混じり文とふりがなを基に、HTMLのrubyタグでふりがなをコーディングするコードは以下のようになります。

javascript

1function generateRubyTag(kanji, furigana) { 2 // 文字列を文字ごとに分割 3 const kanjiArray = Array.from(kanji); 4 const furiganaArray = Array.from(furigana); 5 6 let rubyTag = ''; 7 8 // 文字ごとにループしてrubyタグを生成 9 for (let i = 0; i < kanjiArray.length; i++) { 10 const kanjiChar = kanjiArray[i]; 11 const furiganaChar = furiganaArray[i]; 12 13 // rubyタグを生成して連結 14 rubyTag += `<ruby>${kanjiChar}<rt>${furiganaChar}</rt></ruby>`; 15 } 16 17 // 最終的な出力のHTMLタグを生成 18 const output = `<p>${rubyTag}</p>`; 19 20 return output; 21} 22 23// 例の入力に対して出力を生成 24const kanjiInput = "中々な金物"; 25const furiganaInput = "なかなかなかなもの"; 26const outputHTML = generateRubyTag(kanjiInput, furiganaInput); 27 28console.log(outputHTML);

このJavaScriptのコードでは、generateRubyTagという関数を定義しています。この関数は、かな漢字混じり文とふりがなを受け取り、HTMLのrubyタグを生成します。文字列を文字ごとに分割し、ループを使って各文字に対応するrubyタグを生成します。最終的に、生成されたrubyタグを<p>タグで囲み、出力のHTMLタグを生成します。

上記のコードを実行すると、以下のような出力がコンソールに表示されます。

html

1<p><ruby>中々<rt>なかなか</rt></ruby><ruby>金物<rt>かなもの</rt></ruby></p>

この出力は、指定したかな漢字混じり文とふりがなに基づいて、HTMLのrubyタグが正しく生成された結果です。


コードを試してみましたが、動作しませんでした。ChatGPTには問題は解決できるのですが、それをアルゴリズムにするのはやはり難しいようですね。

投稿2023/06/29 08:53

Lhankor_Mhy

総合スコア37461

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yutampp

2023/07/03 01:02

回答ありがとうございます。 ちょっと複雑になると期待通りに差分をとってくれないことがあるんですよね。 jsdiffのデモサイトで「庭には二羽鶏がいる」という文章の差分をとるとなぜか「わに」が出現します。 http://incaseofstairs.com/jsdiff/ '''html <pre id="result"><del>庭</del>に<ins>わに</ins>は<del>二羽鶏</del><ins>にわにわとり</ins>がいる</pre> ''' これについてはgoogle-diff-match-patch というライブラリでセマンティッククリーンアップをしないでやったところ試した限りでは問題発生しませんでしたのでそれを使うことにしました。 '''html <div id="outputdiv"><del style="background:#ffe6e6;">庭</del><ins style="background:#e6ffe6;">にわ</ins><span>には</span><del style="background:#ffe6e6;">二羽鶏</del><ins style="background:#e6ffe6;">にわにわとり</ins><span>がいる</span><br>Time: 0s</div> '''
yutampp

2023/07/03 01:11

あ、でも「李も桃も桃のうち」は駄目ですね。 李が「すもももももも」になってしまう。
guest

0

chrome用のふりがな拡張機能とかでよければサテライトオフィスから無償版が提供されているようです

投稿2023/06/29 07:57

yambejp

総合スコア117837

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yutampp

2023/07/03 01:05

回答ありがとうございます。 単に読みやすいようにしたいわけではなく、画像に変換したいので、ちょっと違うんですよね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問