長い文章を一定の文字数で改行する正規表現
日付 | 2009/10/28 |
---|---|
ID | 75893 (英語原文参照) |
バージョン | 11 |
プラットフォーム | Mac & Win |
下記のように長い文章を一定の文字数で改行させることは、4D 2004以前ではなかなかたいへん"でした。
> Lorem ipsum dolor sit amet, risus aliquam sollicitudin pede egestas
> massa libero, cursus integer sed quis et molestie metus, nulla pede
> adipiscing sed orci, ac eu consectetuer et massa adipiscing, sed blandit
> ligula enim turpis rutrum imperdiet. Hendrerit quam tincidunt viverra
> lacus, sem dolor venenatis ultrices mauris, praesent egestas eleifend
> inceptos metus rutrum, nullam nec maecenas erat et fusce nibh, elit
> pellentesque sed amet et adipiscing. Lacus urna et nunc, odio ipsum,
> posuere viverra praesent voluptatum urna ut scelerisque, massa commodo
> velit. In dictumst at cras. Eget feugiat. Mollis inceptos convallis eros
> sapien, facilisis scelerisque mauris mauris orci magna. Dolor arcu
> temporibus, maecenas et porta arcu.
4D v11 SQLは、Match regexコマンドで正規表現が使用できるので、こうした処理が非常に簡単です。
はじめに、単語の途中で改行が入らないように、境界(ワードワウンダリー)でマッチする正規表現が必要です。次に、一行の最大文字数を超えないように、文字数の範囲を指定する必要があります。扱う文字がASCII(0-127)に限られていれば、次のような正規表現でじゅうぶんでしょう。
$Pat_T:="(?:[ -~]{1,72}(?:$|\\s))"
(?:regex) はノンキャプチャリングと呼ばれるパターンです。このパターンにマッチした文字列は、メモリにスタックされません。パターンが出現する位置だけが問われている場合、このような正規表現が使用されます。
"[ -~]"という正規表現は、32(スペース)から126(チルダ)まで、という意味です。次の"{1,72}"という正規表現は、最少で1、最多で72という文字数の出現回数を指定しています。最後の"(?:$|\\s)"という表現は、やはりノンキャプチャリングで、$(文字列の終末、キャレッジリターンあるいはラインフィード)または\s(ホワイトスペース文字)を意味します。いずれも基本の正規表現です。
基本の正規表現について
http://www.regular-expressions.info/reference.html
http://www.regular-expressions.info/refadv.html
しかしながら、このような正規表現では、フルセットのUnicodeに対応できているとはいえません。4DはUnicodeアプリケーションなので、次のような正規表現のほうが適切です。
$Pat_T:="(?:[^\\p{C}]{1,72})(?:$|\\p{Z})"
ノンキャプチャリングのグループを使用している点は一緒ですが、パターンが違っています。 "[^\\p{C}]"とは、未使用のコードポイントおよび制御文字のプロパティ(\p{C})ではない(^)という意味です。次の"{1,72}"は、文字数の範囲を指定しています。"(?:$|\\p{Z})"は、"(?:$|\\s)"に似ていますが、あらゆるホワイトスペース文字と非表示プロパティを包含しており、より包括的です。
Unicode版の正規表現およびUnicode文字のプロパティについて
http://www.regular-expressions.info/unicode.html#prop
http://www.regular-expressions.info/refunicode.html
正規表現を使用して改行を挿入するには次のようなコードを記述します。
$Start_L:=1 $FoundAt_L:=0 $Length_L:=0 $Bool_B:=Match regex($Pat_T;$Buf_T;$Start_L;$FoundAt_L;$Length_L) While ($Bool_B) $Buf_T:=Insert string($Buf_T;"\r> ";$FoundAt_L) ` Plus 3 to account for the inserted characters $Start_L:=$FoundAt_L+$Length_L+3 $Bool_B:=Match regex($Pat_T;$Buf_T;$Start_L;$FoundAt_L;$Length_L) End while
正規表現を使用して配列に分解するには次のようなコードを記述します。
ARRAY TEXT($Fold_aT;0) $Start_L:=1 $FoundAt_L:=0 $Length_L:=0 $Bool_B:=Match regex($Pat_T;$Buf_T;$Start_L;$FoundAt_L;$Length_L) While ($Bool_B) APPEND TO ARRAY($Fold_aT;Substring($Buf_T;$FoundAt_L;$Length_L)) $Start_L:=$FoundAt_L+$Length_L $Bool_B:=Match regex($Pat_T;$Buf_T;$Start_L;$FoundAt_L;$Length_L) End while