PHPのwordwrap関数のマルチバイト対応版をMySQLのUDFとしてつくりました。
いつものようにcgoで作ってます。
https://github.com/shigenobu/mysql_ws_wordwrap
PHPのwordwrap関数は以下のリンクとなります。
(PHPのwordwrap)
https://www.php.net/manual/ja/function.wordwrap.php
今回作ったUDFのポイントは、なるべくPHPの関数の第4引数(cut_long_words)をtrueの状態にしたものとなります。
で、このPHPのwordwrap関数の特徴として、何度やっても同じになる(微妙な表現ですが)になるってことなのかと思います。
php > $input = 'aa<br>abbbccc<br>dddee<br>e';
php > $dst1 = wordwrap($input, 3, '<br>', true);
php > echo $dst1;
aa<br>abb<br>bcc<br>c<br>ddd<br>ee<br>e
php > $dst2 = wordwrap($dst1, 3, '<br>', true);
php > echo $dst2;
aa<br>abb<br>bcc<br>c<br>ddd<br>ee<br>e
php > echo (int) $dst1 == $dst2;
1
つまり、breakワードが分割位置に含まれていたら、そこで分割せずに、breakワードを残しつつ、次以降の文字列の評価を行うものなのかと。
※なんていうアルゴリズムなのかわからなかったので、正解ではないかもしれません。
作り始めた当初は、breakワードを一旦消してから、指定文字数でbreakワードいれればいける?と思っていたのですが、
もとの文章にbreakワードが入っている場合、それを消してしまうことになるので、それはちょっと違うかなと思い、
breakワードの位置を探しつつ、構築する形にしてみました。
なんでこんな関数を作ったのかというと、mroongaを使っていた際、
mecab_sparse_tostr() failed len=xxxxx err=too long sentence
というエラーがでたので、これってmecabのストップワードがないから?と思ってしまい、
それなら強制的にwordwrapさせればいける?と思い、作りました。
実際には、文書自体が長過ぎるとエラーになるようで、この関数では解決しなかったんですが。。
本来ならストップワードを指定して分割する形も考えたのですが、急ぎで対応する必要があったので、
今後ヒマがあったら考えみようかと思います。
以上