更新: CSS でこれを処理するのは驚くほど簡単で、オーバーヘッドは低くなりますが、ブレークが発生したときにどこでブレークが発生するかを制御することはできません。気にしない場合、またはデータに自然な区切りのない長い英数字が含まれている場合は問題ありません。多くの長いファイル パス、URL、および電話番号がありましたが、そのすべてに、他の場所よりも断ち切りやすい場所がありました。
私たちの解決策は、最初に正規表現の置換を使用して、空白または改行を好む特殊文字の 1 つ以外の 15 文字 (たとえば) の後に幅ゼロのスペース () を置くことでした。次に、これらの特殊文字の後にゼロ幅のスペースを配置する別の置換を行います。
ゼロ幅のスペースは画面に表示されないので便利です。データには重要なハイフンが含まれているため、恥ずかしがり屋のハイフンは表示されたときに混乱を招きました。ブラウザーからテキストをコピーする場合、ゼロ幅のスペースも含まれません。
現在使用している特殊なブレーク文字は、ピリオド、スラッシュ、バックスラッシュ、カンマ、アンダースコア、@、|、およびハイフンです。ハイフンの後の改行を奨励するために何かをする必要はないと思うかもしれませんが、Firefox (少なくとも 3.6 と 4) は、数字 (電話番号など) で囲まれたハイフンで自動的に改行しません。
また、使用可能なレイアウト スペースに基づいて、人為的な区切りの間の文字数を制御したいと考えていました。つまり、長い非中断実行に一致する正規表現は動的である必要がありました。これは頻繁に呼び出されるため、パフォーマンス上の理由から同じ正規表現を何度も作成したくなかったため、正規表現とそのフラグをキーとする単純な正規表現キャッシュを使用しました。
コードは次のとおりです。おそらく、ユーティリティ パッケージ内の関数に名前空間を設定します。
makeWrappable = function(str, position)
{
if (!str)
return '';
position = position || 15; // default to breaking after 15 chars
// matches every requested number of chars that's not whitespace or one of the special chars defined below
var longRunsRegex = cachedRegex('([^\\s\\.\/\\,_@\\|-]{' + position + '})(?=[^\\s\\.\/\\,_@\\|-])', 'g');
return str
.replace(longRunsRegex, '$1​') // put a zero-width space every requested number of chars that's not whitespace or a special char
.replace(makeWrappable.SPECIAL_CHARS_REGEX, '$1​'); // and one after special chars we want to allow breaking after
};
makeWrappable.SPECIAL_CHARS_REGEX = /([\.\/\\,_@\|-])/g; // period, forward slash, backslash, comma, underscore, @, |, hyphen
cachedRegex = function(reString, reFlags)
{
var key = reString + (reFlags ? ':::' + reFlags : '');
if (!cachedRegex.cache[key])
cachedRegex.cache[key] = new RegExp(reString, reFlags);
return cachedRegex.cache[key];
};
cachedRegex.cache = {};
次のようにテストします。
makeWrappable('12345678901234567890 12345678901234567890 1234567890/1234567890')
更新 2:少なくとも一部の状況では、実際にはゼロ幅のスペースがコピーされたテキストに含まれているように見えますが、それらを見ることはできません。明らかに、隠し文字を含むテキストをコピーすることを人々に奨励することは、そのようなデータを他のプログラムやシステム (自分自身のものであっても) に入力することへの勧誘であり、そこで問題が発生する可能性があります。たとえば、データベースに格納された場合、それに対する検索は失敗する可能性があり、このような検索文字列も失敗する可能性があります。このように矢印キーを使用してデータ間を移動するには、見えない文字を移動するために (当然のことながら) 余分なキーを押す必要があります。
閉じたシステムでは、入力時にその文字を除外して身を守ることができますが、それは他のプログラムやシステムには役立ちません。
全体として、この手法はうまく機能しますが、ブレークを引き起こすキャラクターの最良の選択が何であるかはわかりません.
更新 3:この文字がデータに含まれることは、もはや理論的な可能性ではなく、観測された問題です。ユーザーは画面からコピーされたデータを送信し、データベースに保存され、検索が中断し、物事が奇妙にソートされます.
次の 2 つのことを行いました。
- このアプリのすべてのデータソースのすべてのテーブルのすべての列からそれらを削除するユーティリティを作成しました。
- これを標準の文字列入力プロセッサから削除するためのフィルタリングを追加したため、コードが認識した時点で削除されています。
これは、テクニック自体と同様にうまく機能しますが、注意が必要です。
更新 4:これに供給されるデータが HTML エスケープされている可能性があるコンテキストでこれを使用しています。適切な状況下では、HTML エンティティの途中にゼロ幅のスペースを挿入することができ、奇妙な結果になります。
修正は、次のように、中断しない文字のリストにアンパサンドを追加することでした。
var longRunsRegex = cachedRegex('([^&\\s\\.\/\\,_@\\|-]{' + position + '})(?=[^&\\s\\.\/\\,_@\\|-])', 'g');