10万冊近いマンガのタイトルから巻数を取得する関数、巻数関数を作ったら思ったよりかなり大変だった話

# マンガのタイトルから巻数を取得したい
[自作サービス](https://manga-yonda.com)でマンガのタイトルから**巻数**を取りたくなった。マンガのタイトルで、巻数は何処に書いてあるか？例えば[集英社](https://www.s-manga.net/)の「[HUNTER×HUNTER 1](https://www.s-manga.net/items/contents.html?isbn=4-08-872571-9)」。見ての通り最後に1と書いてある。つまりタイトルの最後に書かれている数字を取得すれば巻数が取れそうだ。ただし、出版社によってルールは若干違い、[小学館](https://comics.shogakukan.co.jp/)は「[名探偵コナン　１](https://www.shogakukan.co.jp/books/09123371)」、[講談社](http://kc.kodansha.co.jp/)は「[はじめの一歩（１）](http://kc.kodansha.co.jp/product?item=0000005071)」、[秋田書店](https://www.akitashoten.co.jp)は「[ドカベン 第1巻](https://www.akitashoten.co.jp/comics/4253030637)」だ。

# 区切り文字の後の文字列から数字を抜き取ったものが巻数
ただ、巻数は何文字か分からない。それよりもタイトルと巻数の間に、空白や括弧のような区切り文字がある。出版社に合わせて、タイトルと巻数の区切り文字の後の**文字列**を取得すると、集英社と小学館は「1」、講談社は「１）」、秋田書店は「第1巻」という文字列が取れる。この文字列から正規表現などで数字だけを抜き取るようにすると無事タイトルから巻数を取得できる。最初は僕もこの方法だった。しかし、この方法では全体の6～7割ぐらいしか巻数を取得できなかった。

# 巻数を取得できないケース1 漢数字巻数
巻数を取得できないケース、最初は**数字**の問題だ。正規表現[0-9]で数字を取得したが、これだと**アラビア数字**しか取れない。巻数表記に使われる数字はアラビア数字とは限らない。例えば「[NARUTO総集編 うずまき大巻 大巻ノ一](https://manga-yonda.com/manga?isbn=9784081110018)」。漢数字にも対応する必要がある。その際は**一二三四五六七八九十**では足りない。巻数に旧字体の漢数字を使うマンガもある。例えば「[修羅の刻（壱）](https://manga-yonda.com/manga?isbn=9784063709346)」。**壱弐参伍什**などの対応も必要だ。さらに二十巻以上になると桁対応を考えなくてはいけない。二十二巻を数字変換して2 +10+2巻では駄目だ。

# 巻数を取得できないケース2 ローマ数字巻数
忘れちゃいけないのがローマ数字だ。身近（？）な所だとゲームのドラクエⅢやFFVがローマ数字だ。当然マンガにもローマ数字の巻数表示がある。例えば「[天の神話 地の永遠 Ⅱ](https://manga-yonda.com/manga?isbn=9784253096294)」。**ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩ**の対応が必要だ。さらにこの漫画の巻数表記は詳しく見ると罠がある。1桁のローマ数字は環境依存文字で全て1文字だ。ところが11巻以降は、アルファベットの**I,V,X**を組み合わて2文字の英語をローマ数字に当てている。例えば11巻なら**Ⅺ**ではなくて**XI**。英語のIやXを単純に数字に変換してしまうと、タイトルの文字にIやXがあった場合も変換されてしまうので注意が必要だ。

# 巻数を取得できないケース3 上中下巻
もう一つ数字ではないが、3冊以下のマンガでは上下巻や上中下巻がある。例えば「[餓狼伝BOY 上巻](https://manga-yonda.com/manga?isbn=9784253217095)」。これも巻数として取得したい。理想は上巻を1巻。下巻を2巻にしたい。ところが中巻がある場合は、上巻は1巻、中巻は2巻、下巻は3巻だ。つまり下巻は冊数によって巻数が変わってしまう。もし、下巻を2巻にするなら、そのマンガは上下巻なのか、上中下巻なのかを事前に知っておく必要がある。

# 巻数を誤認識するケース1 全角半角
数字も区切り文字もだが、全角と半角がある。特に小学館はルールが決まっていないのか、半角数字も全角数字も半角空白も全角空白も同じぐらいある。また、他の出版社はルールは決まっているが、ミスがあってたまに全角になっていることなんかもある。つまりタイトルには半角全角両方混じっている前提で空白と数字は変換する対応が必須だ。

# 巻数を誤認識するケース2 別の意味の数字が巻数に
正規表現などで文字があっても数字だけに限定する仕組みをいれると、誤認識が出てくる。例えば「[終わりのセラフ TVアニメ公式ファンブック 108-HYAKUYA-]()」だ。勿論この漫画は108巻ではない。これに対応すると、全ての文字をスルーするのではなく、()や第○巻などの巻数の装飾としての文字は省き、そうでない文字があった場合無効とする処理が必要になる。巻数装飾は「第○巻、()、VOL」などあるし、巻数数字のような独自のルールがあるかもしれないので、カバーしきれるか難しい所だ。

# 巻数を誤認識するケース3 巻数ではない数字
数字として書かれているが、巻数として認識されると困るものもある。例えば「[『僕のヒーローアカデミア』コミックカレンダー2020](https://www.s-manga.net/items/contents.html?isbn=978-4-08-908363-5)」である。これは当然2020巻ではない。巻数としての最大値が分かっていれば、例えば500以上の数字は巻数にしないという逃げ道もあるが、ここにも罠があって、「[こちら葛飾区亀有公園前派出所999巻](https://www.s-manga.net/items/contents.html?isbn=978-4-08-870358-9)」や「[ONEPIECE ワンピース 千巻](https://www.amazon.co.jp/ONEPIECE-%E3%83%AF%E3%83%B3%E3%83%94%E3%83%BC%E3%82%B9-2%E5%86%8A%E3%82%BB%E3%83%83%E3%83%88-%E3%82%B9%E3%83%88%E3%83%AD%E3%83%B3%E3%82%B0%E3%83%AF%E3%83%BC%E3%83%AB%E3%83%89-1000%E5%B7%BB/dp/B01N2WDN5A/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=%E3%83%AF%E3%83%B3%E3%83%94%E3%83%BC%E3%82%B9+1000&qid=1566553426&s=books&sr=1-1)」などがあったりするので注意が必要だ。

# 巻数を誤認識するケース4  巻数が最後にない
巻数の数字を取得できない以外にも、巻数がタイトルの最後にないケースがある。例えば「[宇宙兄弟（１１）限定版](http://kc.kodansha.co.jp/product?item=0000011408)」だ。限定版という文字を抜くという対応では駄目で、例えば「[おやすみプンプン　７　限定版　特製フィギュア付色鉛筆７体セット付](https://www.amazon.co.jp/%E3%81%8A%E3%82%84%E3%81%99%E3%81%BF%E3%83%97%E3%83%B3%E3%83%97%E3%83%B3-7-%E9%99%90%E5%AE%9A%E7%89%88-%E7%89%B9%E8%A3%BD%E3%83%95%E3%82%A3%E3%82%AE%E3%83%A5%E3%82%A2%E4%BB%98%E8%89%B2%E9%89%9B%E7%AD%867%E4%BD%93%E3%82%BB%E3%83%83%E3%83%88%E4%BB%98-%E3%83%A4%E3%83%B3%E3%82%B0%E3%82%B5%E3%83%B3%E3%83%87%E3%83%BC%E3%82%B3%E3%83%9F%E3%83%83%E3%82%AF%E3%82%B9/dp/4091590284)」など何が書いてあるか把握しきれないぐらいパターンがある。この状態で巻数をとるなら最後の区切り文字ではなく、巻数数字があるまで区切り文字を辿っていく必要がある。例えば「特製フィギュア付色鉛筆７体セット付」→「限定版」→「７」で7巻が取れる。

# 巻数を型として扱うのに
別の話で、巻数を入れる型だが、intでは駄目で、doubleが良い。何故かというと、普通に小数の巻数表記があるからだ。例えば「[新テニスの王子様 10.5](https://www.s-manga.net/items/contents.html?isbn=978-4-08-870879-9)」。最初intだったので、この漫画の巻数は取れなかった。さらに、「[こち亀∞巻](http://www.j-kochikame.com/mugen/)」というタイトルがある。∞はint型では無効な数字だが、（少なくともC#では）double型では有効な数字だ。また別の話で無効値を0にするのはやめた方が良い、「[ハヤテのごとく！　第０巻](https://www.shogakukan.co.jp/books/09123736)」など0巻を冠するマンガもある。-1にするのが無難だ。但し、-1巻のマンガが出ないとも限らない。-∞にするのが良いかもしれない。

# マンガのタイトルから巻数を取得する関数
ここまでのルールで巻数を作ってみた。

```csharp
1. タイトルの()と（）を半角空白に置換、全角空白を半角空白に置換（「タイトル(1)」には空白がないので空白にする）
2. 最後の半角空白の後の文字列を取得（この文字列こそが巻数だが、第１巻など装飾がつくことが多い）
3. 取得した文字列のアラビア数字以外の数字（一～十、Ⅰ～Ⅻ、I～XX、上中下、壱など）をアラビア数字に置換する
4. 取得した文字列の余計な装飾（第、(完)、VOL.など）を空文字に置換（正規表現で数字だけにすると例えばPS4も巻数になる）
5. 取得した文字列をdoubleにパース。成功したらそれが巻数。（intだと24.5など小数の巻数が取れない）
6. ここまでで巻数取れなかったら、タイトルの前回の1個手間の半角空白文字に対して同じ処理をおこうなう。
7. 半角空白がなくなるまで繰り返しても数字が取れなかったら巻数を-1にする。（0巻はあるので-1。）
```

# 巻数を取得できないケース1 1巻のみ表記なし
ここまでやって9割近くの巻数はとれるようになったが、まだ10割は無理だった。ダメなケースの1つは1巻だけ「1巻」と書かず、2巻以降のみナンバリングされるケースだ。例えば「[/Blush-DC](https://www.s-manga.net/items/contents.html?isbn=978-4-08-782254-0)、[/Blush-DC 2](https://www.s-manga.net/items/contents.html?isbn=978-4-08-782346-2)」。少なくともマンガのタイトルに書いてないので1巻を取ることはどうやっても出来ない。巻数がないものを1巻として扱う手はあるが、その場合、実際に巻数がないマンガと区別することは出来ない。他の全タイトルをチェックして2巻があるものと同じタイトルで数字がなければ1巻とすれば出来なくないが、あまりやりたくない。

# 巻数を取得できないケース2 独自巻数表記
さらに独自に巻数を作っている例もある。例えば「[NARUTO―ナルト― TVアニメプレミアムブック NARUTO THE ANIMATION CHRONICLE ](https://www.s-manga.net/items/contents.html?isbn=978-4-08-792514-2)」は「天、地」。「[妖怪ハンター](https://www.amazon.co.jp/%E5%A6%96%E6%80%AA%E3%83%8F%E3%83%B3%E3%82%BF%E3%83%BC-%E5%9C%B0%E3%81%AE%E5%B7%BB-%E9%9B%86%E8%8B%B1%E7%A4%BE%E6%96%87%E5%BA%AB-%E8%AB%B8%E6%98%9F-%E5%A4%A7%E4%BA%8C%E9%83%8E/dp/4086183900/ref=pd_lpo_sbs_14_t_1?_encoding=UTF8&psc=1&refRID=E9R12A8JBQXG92PDNDPF&fbclid=IwAR1TRhvPoRES0QjKYdJSLIs8tD9FhkS4Ciu7REN0mKy7AGik2PawEaRftn0)」は「天、地、水」（…人じゃないのか！）。「[霊感工務店リペア](https://www.s-manga.net/search/search.html?seriesid=37546&order=1)」は、「怪、妖、異、驚、玄、幽、烈、天、奇、議、思、不、訶」（…？！）。「[電脳なをさん](https://www.amazon.co.jp/gp/product/B074C3SDNH?ref_=dbs_r_series&storeType=ebooks)」に至っては、「Ver.1.0、Ver.2.0、黒の巻、白の巻」だ。黒って何巻やねんって話だ。諸星大二郎も唐沢なをきも内容はいくら尖ってくれても良いけど、巻数表記ぐらい普通につけてくれと思う。

# 巻数を取得できないケース3 区切り文字がない
またタイトルと巻数の間に区切りがないものもある。区切りがないものの対応もかなり厳しい。例えば、「[大長編ドラえもん1　のび太の恐竜](https://www.shogakukan.co.jp/books/09140602)」だ。これに対して空白の前の数字を巻数にするみたいなルールを作ると、そのルールにヒットして誤認識が出てしまう。もっと酷いのが「[究極超人あ～る１通常版](https://www.shogakukan.co.jp/books/09860183)」で、これにいたっては、空白も区切り文字も何もない。もうどういうルールにしても誤認識してしまう可能性が高い。この漫画専用の条件分岐を作るか、出版社側にサイトの表記を直してもらうしかない気がする。

# 出版社のサイト表記が変わる例
そもそも出版社が表記を変えることはよくある。最近だと集英社の「[遊☆戯☆王](https://www.s-manga.net/items/contents.html?isbn=978-4-08-618574-5)」は長いことタイトルが「遊・戯・王」だったが、「遊☆戯☆王」に変わった。何年も・だったのに、ある日突然タイトルが☆になったのだ。ただ実際表紙を見ると☆で書いてある。これを考えると現状対応しなくても済んでいるが、対応しなければならないケースはいくらでも考えられる。①とか②とかは現状入れてないが、必要になるかもしれない。-1巻もあり得る。なので今現在の100%対応を作っても、明日失敗するケースがあるかもしれない。これ以上の精度を追求していくのであれば、ディープラーニングで取れる仕組みにしていく方が良い気もしている（が、そっちに明るくないので、今より精度があげられるかは分からない）。

# まとめ
10万冊近いマンガのタイトルから巻数を取得する関数、**巻数関数**を作ろうとしたら、思ってたよりかなり大変だった。でも、巻数がとれるようになったため、[自作サービス](https://manga-yonda.com)で巻数ソートも出来るようになったし、タイトルからのシリーズ分けの精度も上がったり、副産物的に限定版の取得なども出来るようになった。タイトルから巻数を取るのに困ったら？是非参考にしてほしい（さらなる情報を共有してくれると嬉しいなー）。