質問: テキストエディタの正規表現です。主にBoost.RegexとOnigmoです。 EmEditor Professional Windows10 64ビット版 文章で20文字以内に改行しなければならないときに、それまで改行できている行はそのままにして、20文字以上超えている文章の行は、最短で改行させたいです。 以下、正規表現で改行したい文章の事例です。 35文字 ``` きのうは、武史くんと、いっしょに、野球ができたので、たのしかったです。 ``` この文章は20文字を超えているので、制限文字数オーバーをしています。 そこで20文字以内の一番近いところである以下で改行できるようにしたいのです。 ``` きのうは、武史くんと、いっしょに、 野球ができたので、たのしかったです。 ``` このように20文字を超えている文章については、最も20文字目から近いところの区切りになる "、" "?" "を" これらのどれらか20文字目に近いほうで改行するという正規表現にしたいのです。 これは、文字数制限のある改行が必要な問題で、なるべく文章を長くしたいけれども20文字以内では改行しなければならないという制限があるためです。 実際はもっと長い文字数で改行ですが、簡易的な例題をつくって、説明を簡単にするために20文字以内ということにしました。 よろしくお願いいたします。
回答: Boost.Regex も Onigmo も手元の環境では利用できませんので、PCRE(Perl Compatible Regular Expressions) を使用してみました。参考にしてみて下さい。 手法としては 5桁以内の半角数字でかつ「0だけ」は許可しない正規表現 と同じで、最初に 20 文字を肯定先読み(`positive lookahead`)します。その上で `、`, `。`, `?`, `を` の出現を最長マッチで探索します(「文」の区切りという事なので句点(`。`)を追加しています)。 ``` $ echo 'きのうは、武史くんと、いっしょに、野球ができたので、たのしかったです。' | grep -Po '((?=.{20})(.{0,19}([、。?を]))|.{0,20})' => きのうは、武史くんと、いっしょに、 野球ができたので、たのしかったです。 ``` ここで最短マッチ(`.{0,19}?`)にしてしまうと以下の様になってしまいます。 ``` $ echo 'きのうは、武史くんと、いっしょに、野球ができたので、たのしかったです。' | grep -Po '((?=.{20})(.{0,19}?([、。?を]))|.{0,20})' きのうは、 武史くんと、 いっしょに、 野球ができたので、たのしかったです。 ``` * 文章が41文字以上ある場合 ``` cat < きのうは、武史くんと、いっしょに、 野球ができたので、たのしかったです。 今日は、雨で、外で遊べなかったので、 ちょっぴり悲しかったです。 ``` * 20文字以内に区切り文字が含まれていない場合 ``` $ echo 'きのうは武史くんといっしょに野球ができたのでたのしかったです。' | grep -Po '((?=.{20})(.{0,19}([、。?を]))|.{0,20})' => きのうは武史くんといっしょに野球ができた のでたのしかったです。 ```