tag:crieit.net,2005:https://crieit.net/tags/Kuromoji.js/feed 「Kuromoji.js」の記事 - Crieit Crieitでタグ「Kuromoji.js」に投稿された最近の記事 2019-09-29T11:29:48+09:00 https://crieit.net/tags/Kuromoji.js/feed tag:crieit.net,2005:PublicArticle/15434 2019-09-29T11:28:32+09:00 2019-09-29T11:29:48+09:00 https://crieit.net/posts/Web-5d9016d040fdf フロント明るくないおじさんがWebアプリ作った話【悟空語ジェネレーター】 <blockquote> <p>2019年2月に<a target="_blank" rel="nofollow noopener" href="https://qiita.com/kinmi/items/c66aa98718acad84621b">Qiitaへ投稿</a>した記事のクロス投稿です。</p> </blockquote> <h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1> <p>近年、個人開発がとても盛んになってきました。<br /> クラウドサービスのリッチ化に伴い、個人でも簡単にWebサービスを運営できる時代となり、<br /> 個人開発者の熱意が更なる個人開発者の熱意を生む、素晴らしい連鎖が発生しています。</p> <p>特に去年、2018年は爆発的な個人開発ブームでした。</p> <p><em>「企業の一兵隊だった自分でも、何者かになれるんじゃないか」</em></p> <p><em>「世界は俺のプルリクを待っているのではないか」</em></p> <p>そう思わせてくれる1年でした。</p> <p>かく言う私も、その熱意にあてられ去年1年間、<br /> ひたすら<strong>Qiitaを傍観</strong>していました。</p> <p>私の業務はずっとサーバーサイドのJava開発。<br /> フロント明るくないおじさんです。<br /> はじめまして。きんみと申します。以後よろしくお願いします。</p> <h1 id="作ったもの"><a href="#%E4%BD%9C%E3%81%A3%E3%81%9F%E3%82%82%E3%81%AE">作ったもの</a></h1> <p>とは言え、私も兵隊の端くれ。<br /> 血湧き肉躍る開発は大好物なわけでして。<br /> Web開発の真似事のような事はやっていました。<strong>年末頃</strong>から。<br /> その集大成がこちらになります。</p> <p><strong>悟空語ジェネレーター</strong><br /> <a target="_blank" rel="nofollow noopener" href="https://goku-lang.netlify.com/">https://goku-lang.netlify.com/</a><br /> <img src="https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F127547%2F0fb19b09-cfc8-e408-bfe9-48c66a21397d.gif?ixlib=rb-1.2.2&auto=compress%2Cformat&gif-q=60&w=1400&fit=max&s=d00e45fecad196cc77e243f27355def9" alt="悟空語ジェネレーター" /><br /> 日本語を入力すると、悟空語に変換します。<br /> 初回はブラックボックスなサービスとして遊んで頂きたいので、<br /> 変換ルールについては最後に書きます。</p> <h1 id="使った技術"><a href="#%E4%BD%BF%E3%81%A3%E3%81%9F%E6%8A%80%E8%A1%93">使った技術</a></h1> <p><a target="_blank" rel="nofollow noopener" href="https://jp.vuejs.org/index.html">Vue.js</a><br /> JavaScript三大フレームワークの1つ。<br /> 公式ドキュメントの日本語がとても丁寧で、初学者の私でもとっつきやすいと感じたため使ってます。</p> <p><a target="_blank" rel="nofollow noopener" href="https://www.npmjs.com/package/kuromoji">kuromoji.js</a><br /> JavaScript製 形態素解析ライブラリ。<br /> 形態素とは文節の最小単位で、日本語文字列をこの単位で分解して、読み仮名や品詞情報を付与してくれます。<br /> <a target="_blank" rel="nofollow noopener" href="https://takuyaa.github.io/kuromoji.js/demo/tokenize.html">こちら</a>のデモサイトが分かりやすいです。</p> <p><a target="_blank" rel="nofollow noopener" href="https://www.netlify.com/">Netlify</a><br /> 静的ホスティングサービス。<br /> ちょー簡単にWEBサイト作れます。</p> <p>ということで、このサービスは静的なサイトです。<br /> 冒頭に話した「リッチなクラウドサービス」は、ほぼ<strong>使ってません</strong>。<br /> 流行りのNetlifyを使ってますが、別にどこだろう動きます。<br /> <strong>故・Yahoo!ジオシティーズ</strong>でも多分動きます。</p> <p>紆余曲折を経ての結果ですが、ちょっと後悔しています。<br /> 後述します。</p> <h1 id="仕組み"><a href="#%E4%BB%95%E7%B5%84%E3%81%BF">仕組み</a></h1> <ol> <li>入力値をkuromoji.jsで形態素解析</li> <li>各形態素の読み仮名情報をローマ字に変換</li> <li>変換ルールに従い、正規表現でゴリゴリ変換</li> <li>変換された形態素はひらがなへ戻す</li> <li>変換されなかった形態素は元キーワードへ戻す</li> <li>全形態素を文字列結合</li> </ol> <p>たったこれだけです。</p> <h1 id="ハマったところ"><a href="#%E3%83%8F%E3%83%9E%E3%81%A3%E3%81%9F%E3%81%A8%E3%81%93%E3%82%8D">ハマったところ</a></h1> <h2 id="1. フロントゼンゼンワカラナイ"><a href="#1.+%E3%83%95%E3%83%AD%E3%83%B3%E3%83%88%E3%82%BC%E3%83%B3%E3%82%BC%E3%83%B3%E3%83%AF%E3%82%AB%E3%83%A9%E3%83%8A%E3%82%A4">1. フロントゼンゼンワカラナイ</a></h2> <p>学生時代にHP作った事ありましたし、少しですが業務でjQuery等をイジる事もあります。<br /> しかし、いざ勉強をしてみるとそのカオスっぷりに腰が抜けました。<br /> <strong>フロントなんて刺身にたんぽぽ乗せてるだけ</strong>と思ってた自分を殴りたくなりました。</p> <p>まずは基本となるHTML5、というより<strong>脱TABLEタグ</strong>から入り、<br /> ES6、Vue.js、React等の公式ドキュメントや入門記事をサーフィンして<br /> Hello Worldな日々を4〜5日程続けました。<br /> 広く浅く現代の技術に触れて、無知の知を得る事に徹しました。</p> <h2 id="2. 形態素解析"><a href="#2.+%E5%BD%A2%E6%85%8B%E7%B4%A0%E8%A7%A3%E6%9E%90">2. 形態素解析</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/torao@github/items/45ad9640cf94d3169cae">React + Kuromoji を使ってブラウザ上で形態素解析</a><br /> こちらを参考に、Vue.js上でkuromoji.jsを動かせるようにしました。</p> <p>まずは<code>npm install kuromoji</code>した後、辞書を公開ディレクトリへコピー。</p> <pre><code>$ cd project-directory $ cp -a node_modules/kuromoji/dict public/ </code></pre> <p>下記のようにしてVue.js上でkuromoji.jsを動かしました。</p> <pre><code><template> <div id="app"> <input id="inputText" v-model="inputText"> <button v-on:click="conv">変換</button> <p>outputToken is: <span>{</span><span>{</span> outputToken <span>}</span><span>}</span></p> </div> </template> <script> import kuromoji from "kuromoji" export default { name: 'App', data() { return { inputText: "形態素解析される文字列", outputToken: [], builder: kuromoji.builder({ dicPath: "/dict" }) } }, methods: { conv: async function(event) { var vm = this this.builder.build(await function(err, tokenizer){ if(err){ throw err } else { var token = tokenizer.tokenize(vm.inputText) vm.outputToken = token } }); } } } </script> </code></pre> <p>ポイントは下記です。</p> <p><code>var vm = this</code></p> <p>通常、単一コンポーネント内ではthisでプロパティを参照するが、</p> <p>builder内でも参照できるようにグローバル変数に格納する。</p> <p><code>async / await</code></p> <p>builder.build は非同期処理の為、async / awaitを使う。</p> <p><code>vm.outputToken = token</code></p> <p>形態素解析後のトークンをプロパティへ格納する。</p> <p>この勘所が全く分からずハマり、Vue.js上でkuromoji.jsを動かす事は一度諦めて、下記を検討しました。</p> <ul> <li>代替品として<a target="_blank" rel="nofollow noopener" href="https://github.com/rakuten-nlp/rakutenma/blob/master/README-ja.md">Rakuten MA</a>の使用</li> <li>GoogleCloudFunctions(GCF)にkuromoji.jsを置いてAPI化</li> <li>GCFに<a target="_blank" rel="nofollow noopener" href="https://github.com/miurahr/pykakasi">Pykakasi</a>(Python製 形態素解析ライブラリ)を置いてAPI化</li> <li><a target="_blank" rel="nofollow noopener" href="https://dev.classmethod.jp/server-side/mecab-using-python3-ja/">MecabをPythonで叩く</a>API作成</li> <li>外部APIサービス(<a target="_blank" rel="nofollow noopener" href="https://developer.yahoo.co.jp/webapi/jlp/ma/v1/parse.html">Yahoo!JAPAN テキスト解析WebAPI</a>等)の使用</li> </ul> <p>箇条書きで書きましたがそれぞれ、調査して、コードを書いて、ハマって、諦めてを繰り返してます。<br /> 1行につき1〜2日は費やしています。<br /> もっと頑張れば、いずれも実現可能だったかもしれませんが、最終的に「ブラウザ上でkuromoji.jsを実行」に回帰しました。<br /> 選定した訳ではなく、現段階の私の技術力ではこれしか出来なかったのです。</p> <h2 id="3. ローマ字変換"><a href="#3.+%E3%83%AD%E3%83%BC%E3%83%9E%E5%AD%97%E5%A4%89%E6%8F%9B">3. ローマ字変換</a></h2> <p>今回の処理は、<br /> 入力値をローマ字に変換 → 解析 → ひらがなへ戻す<br /> というフローになります。<br /> 便利なJS製のカナ/ローマ字変換ライブラリがいくつかありましたが、<br /> どれもヘボン式で不可逆でした(とうきょう → tokyo → ときょ)<br /> また、解析は正規表現で行うため[sa,<strong>shi</strong>,su,se,so]のような不規則な変化は避けたく<br /> 可逆なローマ字変換処理を自前で作成しました(とうきょう → toukyou)</p> <h2 id="4. CSSフレームワーク"><a href="#4.+CSS%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF">4. CSSフレームワーク</a></h2> <p>このアプリはドラゴンボールのネタアプリです。<br /> もちろん、CSSフレームワークは<strong>Bulma</strong>(ブルマ)を使ってます(ドヤ</p> <p>言いたかっただけです。特にハマってません。</p> <p>BootstrapからjQuery依存を省いた軽量なCSSフレームワークです。<br /> <a target="_blank" rel="nofollow noopener" href="https://bulma.io/documentation/">公式ドキュメント</a>や、下記記事を参考にサクっと導入出来ました。素晴らしい。<br /> <a target="_blank" rel="nofollow noopener" href="https://qiita.com/ochiochi/items/de1afd2d3fc8f6d3ea55">CSSフレームワーク BULMA チュートリアル①</a></p> <h1 id="マーケティング"><a href="#%E3%83%9E%E3%83%BC%E3%82%B1%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0">マーケティング</a></h1> <p>フロント技術の学習が目的だった為、開発以外の何かを行うつもりはなかったです。<br /> しかし、せっかくWebアプリを公開するならば、使ってもらえるよう努力したい。<br /> これもまたWebの学習。「やらない」はただの機会損失、と思い</p> <p><strong>悟空なりきりアカウントをフォローしてみました。</strong></p> <blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">やったぜ!!!よろしくな!! <a target="_blank" rel="nofollow noopener" href="https://t.co/kVgRtneAMp">https://t.co/kVgRtneAMp</a></p>— きんみ / 🎍ついぎり🎍リリースしました🎉 (@_kinmi) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/_kinmi/status/1087275299161616384?ref_src=twsrc%5Etfw">2019年1月21日</a></blockquote> <p>今のところ、<strong>使って頂いた形跡はありません。</strong></p> <p><em>2019/4追記<br /> いつの間にかこちらのなりきりさん、アカウント削除されてました。。</em></p> <p>しかし、Twitterで公開したことで、多くのフォロワーさんに使って頂き、バグ報告も多数頂戴しました。<br /> テスト不足が露呈した結果ですが、ローカルで動かしていただけじゃ気付かず終わっていたと思います。<br /> 公開して得られる学びの多さを痛感しました。</p> <h1 id="公開後のバグ対応"><a href="#%E5%85%AC%E9%96%8B%E5%BE%8C%E3%81%AE%E3%83%90%E3%82%B0%E5%AF%BE%E5%BF%9C">公開後のバグ対応</a></h1> <h2 id="① iPhoneでは表示されない問題"><a href="#%E2%91%A0+iPhone%E3%81%A7%E3%81%AF%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%81%AA%E3%81%84%E5%95%8F%E9%A1%8C">① iPhoneでは表示されない問題</a></h2> <p>Twitterで公開した直後の出来事でした。</p> <blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">見れないです・・・iPhoneだからですかね(´・ω・`)</p>— 無職やめ太郎(本名) (@Yametaro1983) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/Yametaro1983/status/1091833791142715393?ref_src=twsrc%5Etfw">2019年2月2日</a></blockquote> <p>はい、Chromeでしかテストしてません。。。<br /> Safariで開いてみたところ、ブランクページが表示されました。</p> <p>変換処理で多用していた正規表現の「<a target="_blank" rel="nofollow noopener" href="http://js-next.hatenablog.com/entry/2015/11/20/083622">後読み</a>」が原因でした。<br /> 2019/2現在、対応しているブラウザはChromeだけのようです。<br /> ここでJSが落ち、レンダリング自体されない事態に陥ってました。</p> <p>先読みは使えるとの事だったので下記を参考に、文字列を反転させてマッチさせるという荒技を使いました。<br /> <a target="_blank" rel="nofollow noopener" href="https://qiita.com/yumarule/items/a37520974e39b25b7a6f">Javascriptでの正規表現の後読みの代替</a></p> <h2 id="② ぱい◯いでか美さん対応"><a href="#%E2%91%A1+%E3%81%B1%E3%81%84%E2%97%AF%E3%81%84%E3%81%A7%E3%81%8B%E7%BE%8E%E3%81%95%E3%82%93%E5%AF%BE%E5%BF%9C">② ぱい◯いでか美さん対応</a></h2> <blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">ぱいぱいでか美 <a target="_blank" rel="nofollow noopener" href="https://t.co/ESyx59epVx">https://t.co/ESyx59epVx</a> <a target="_blank" rel="nofollow noopener" href="https://twitter.com/hashtag/%E6%82%9F%E7%A9%BA%E8%AA%9E%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AC%E3%83%BC%E3%82%BF%E3%83%BC?src=hash&ref_src=twsrc%5Etfw">#悟空語ジェネレーター</a>これは「ぺぇぺぇでか美」にならへんのかいw</p>— 無職やめ太郎(本名) (@Yametaro1983) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/Yametaro1983/status/1091859171635412992?ref_src=twsrc%5Etfw">2019年2月3日</a></blockquote> <p>想定外です。ワケが分からない。<br /> ぱい系ワードは沢山テストしたのに、何故でか美さんだけ変換されないのか、、、</p> <p>原因は「ぱいぱいでか」を識別不可なワードとして解析され、<br /> 本来カタカナである読み仮名情報がひらがなになっていました。<br /> 私の仕様把握不足です。<br /> 前提としていた仕様が崩れ、<strong>デスマーチ</strong>が始まります。</p> <blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">やべぇ…でか美さん手強い…原因っぽいの直したら「ぺぇぱいでか美」ってなった、、どんな処理通ったらこうなるんや… <a target="_blank" rel="nofollow noopener" href="https://t.co/gwF0SffzKS">pic.twitter.com/gwF0SffzKS</a></p>— きんみ / 🎍ついぎり🎍リリースしました🎉 (@_kinmi) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/_kinmi/status/1091997573915656199?ref_src=twsrc%5Etfw">2019年2月3日</a></blockquote> <blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">ぐあぁぁあ!!!ちくしょーーーー!!! <a target="_blank" rel="nofollow noopener" href="https://t.co/oLCeRtNyD9">pic.twitter.com/oLCeRtNyD9</a></p>— きんみ / 🎍ついぎり🎍リリースしました🎉 (@_kinmi) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/_kinmi/status/1092001619837743105?ref_src=twsrc%5Etfw">2019年2月3日</a></blockquote> <p>現在は正常に「ぺぇぺぇでか美」となるのでご安心ください。</p> <h1 id="やらなかった事/やれなかった事"><a href="#%E3%82%84%E3%82%89%E3%81%AA%E3%81%8B%E3%81%A3%E3%81%9F%E4%BA%8B%2F%E3%82%84%E3%82%8C%E3%81%AA%E3%81%8B%E3%81%A3%E3%81%9F%E4%BA%8B">やらなかった事/やれなかった事</a></h1> <h2 id="1. バックエンド開発"><a href="#1.+%E3%83%90%E3%83%83%E3%82%AF%E3%82%A8%E3%83%B3%E3%83%89%E9%96%8B%E7%99%BA">1. バックエンド開発</a></h2> <p>当初の学習目標は「Firebase Hosting + Cloud Functionsを使ったサーバレス開発」でした。<br /> しかし、結果としてはバックエンド処理の無い、<strong>文字通りのサーバレス</strong>となってしまいました。</p> <p>辞書ファイルをキャッシュするため、初回の変換は超絶重いうえに、挙動のクライアント環境依存が強すぎます。。<br /> 友人はスマホの速度制限が来ていたのか、<strong>5分</strong>かかったと言っていました。<br /> 別の友人は<strong>Android版Edgeなるもの</strong>を使っていて「動かないよ」と言ってました。<br /> やはり、コアな処理は裏に持たせるべきですね。</p> <p>また、ユーザが変換したワードの収集が出来ません。<br /> リリース後のメンテナンス作業を見越した場合、生きたデータは貴重です。<br /> こんな小さなネタアプリでも、バックエンド処理は作るべきでした。</p> <h2 id="2. OGP作成"><a href="#2.+OGP%E4%BD%9C%E6%88%90">2. OGP作成</a></h2> <p>ここは捨てました。ついでにファビコンもVueデフォルトのままです。<br /> 作り出すと拘ってしまい、リリース延期に繋がると思ったからです。<br /> バズを狙う場合は必須ですが、、、</p> <p>ただ、こちらの記事を拝見して<br /> <a target="_blank" rel="nofollow noopener" href="https://qiita.com/serinuntius/items/3017fb6ef51cd47352f6">Vue.jsとFirebaseでOGP画像生成系のサービスを爆速で作ろう</a><br /> OGPとしてSNSに共有するのは技術的にも面白そうと思ったので、近いうち導入するかもしれません。</p> <h1 id="モチベーション管理"><a href="#%E3%83%A2%E3%83%81%E3%83%99%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E7%AE%A1%E7%90%86">モチベーション管理</a></h1> <p>私のモチベ傾向として、完成までの道筋が見えたら熱が冷めます。<br /> 手探りでやっている時が一番楽しいんですよね。<br /> 過去にはリリースまで行かず、中途半端に終わったスマホアプリが幾つかあります。<br /> 今回も二の舞になるのではないか、という懸念があったので、<br /> 完成が見えた段階で<a target="_blank" rel="nofollow noopener" href="https://qiita.com/jabba">@jabba</a>さん作の<a target="_blank" rel="nofollow noopener" href="https://www.mobet.gq/">mobet</a> を使いました。</p> <blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">週末振休含めて4連休なので٩(๑òωó๑)۶今お遊びで作ってる「悟空語ジェネレーター」を公開する。 <a target="_blank" rel="nofollow noopener" href="https://t.co/Nuhjm7PCtp">https://t.co/Nuhjm7PCtp</a> <a target="_blank" rel="nofollow noopener" href="https://twitter.com/hashtag/%E3%83%A2%E3%83%99%E3%83%83%E3%83%88?src=hash&ref_src=twsrc%5Etfw">#モベット</a> <a target="_blank" rel="nofollow noopener" href="https://twitter.com/_kinmi?ref_src=twsrc%5Etfw">@_kinmi</a>さんから</p>— きんみ / 🎍ついぎり🎍リリースしました🎉 (@_kinmi) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/_kinmi/status/1087988495120023552?ref_src=twsrc%5Etfw">2019年1月23日</a></blockquote> <p>しかし、残念ながらこの4連休に<strong>インフルエンザにかかるという痛恨のミス</strong>を犯してしまい未達成です。<br /> 「未達成と判定するまで(期日から判定まで五日間の猶予があります)には完成させる」をモチベーションにリリースまで漕ぎ着けました。</p> <h1 id="変換ルール"><a href="#%E5%A4%89%E6%8F%9B%E3%83%AB%E3%83%BC%E3%83%AB">変換ルール</a></h1> <p>最後に変換ルールです。<br /> 当アプリの発想は下記ブログエントリーからです。<br /> <a target="_blank" rel="nofollow noopener" href="http://junk.hatenablog.jp/entry/2018/02/15/034507">野沢雅子語の活用けぇ(活用形)</a><br /> 変換ルールはこちらを肉付けした形になります。</p> <p><strong>1. 母音[a, i] + [i, e] => 母音[e] + 'ぇ'</strong><br /> e.g.) 最初 → さいしょ → saisyo → selesyo → せぇしょ</p> <p><strong>2. 品詞:動詞 に含まれる 'る' => 'っ' 文末の場合は 'っぞ'</strong><br /> 文末かつ、動詞+助動詞の場合は後続の助動詞を削除しています。<br /> kuromoji.jsでは単語の原型(サ行変格活用前、等)のワードも取得でき、そちらもチェックしています。<br /> e.g.) するから → surukara → sultukara → すっから<br /> します(する + ます) → suru → sultuzo → すっぞ<br /> 帰ります(かえる + ます) → kaeru → keleltuzo → けぇっぞ(ルール1と2の併用)</p> <p><strong>3. 一人称 => 「おら」、二人称 => 「おめぇ」</strong><br /> Wikipediaから一人称と二人称の一覧を作り、固定値で変換かけてます。<br /> 「貴様」が代名詞として判断されなかったので、「品詞=代名詞」の条件はつけてません。<br /> ベジータの台詞を悟空語に変換したかったので。</p> <p>上記がデフォルト挙動であり、なまりレベル:普通です。<br /> なまりレベル:強い/超 は上記に加えて固有の変換ルールが加わります。</p> <p><strong>強い:母音[o] + [i, e] => 母音[e] + 'ぇ'</strong><br /> e.g.) におい → nioi → niele → にえぇ</p> <p><strong>超:3文字のローマ字(ltu 等)以外の母音全て => 母音[e]</strong><br /> e.g.) オッス!おら孫悟空!→ oltusu!orasongokuu! → eltuse!eresengekee! → えっせ!えれせんげけぇ!<br /> (※1)</p> <p>なまりレベル:超 は文字だとよく分からないですが、<strong>声に出す</strong>と意外と読めます。<br /> 他のルール発見された方は教えてください!</p> <h1 id="おわり"><a href="#%E3%81%8A%E3%82%8F%E3%82%8A">おわり</a></h1> <p>次は、すげぇWEBせぇとつくっぞ。<br /> (次は、凄いWEBサイト作る。)(※2)</p> <h1 id="その他参考サイト"><a href="#%E3%81%9D%E3%81%AE%E4%BB%96%E5%8F%82%E8%80%83%E3%82%B5%E3%82%A4%E3%83%88">その他参考サイト</a></h1> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/hrdaya/items/291276a5a20971592216">JavaScriptで正規表現(文字列置換え編)</a></p> <p>※1 :「孫悟空」だと大丈夫ですが、「悟空」は「さとるそら」と読んでしまいます。<br /> ※2 : なまりレベル:強</p> きんみ