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>
きんみ