web-dev-qa-db-ja.com

列に「スペース」が含まれていない行を検索する

Postgres 9.5を使用しています。名前列にスペースが含まれていない行を検索したい。でも、あなたにスペースをどのように定義するかについては、少し曖昧です。キーボードのスペースバーだけだと思ったので、実行しました。

_.... where name not like '% %';
_

しかし、私はこのような結果を得ました:

_ | JASON FALKNER
_

それは確かに私にはスペースのように見えますが、おそらく他にもいくつかのことが起こっています。名前列にスペースが含まれていない行をスキャンできるより良い方法はありますか?

正規表現を使用した場合でも、not (name ~ '\s')はスペースがあるように見える列を返しました。

使用:

_select cast(name as bytea) ... where name not like like '% %';
_

戻ってきた:

_\x4a41534f4ec2a0424c414b45
_

ただし、結果からスペースを選別する方法を理解するためにそのデータをどのように使用するかは、まだはっきりしていません。

私はwhere not (name ~ '[[:space:]]')'を試しましたが、上記と同じバイトシーケンス_\x4a41534f4ec2a0424c414b45_で「JASON BLAKE」を返しています。

4
Dave

「空白」と見なして正規表現から除外する文字を明示的に指定することをお勧めします。

where name !~ '[ \t\v\b\r\n\u00a0]'

キャラクター:

\s         white space (space, \r, \n, \t, \v, \f)
' '        space
\t         (horizontal) tab
\v         vertical tab
\b         backspace
\r         carriage return
\n         newline
\f         form feed
\u00a0     non-breaking space
---

パターンマッチング のドキュメントを参照してください。

あなたの例では、\xC2A0非分割スペース(00A0) のUTF-8表現です。

6
ypercubeᵀᴹ

次のUnicodeリストに従って、多数のスペース文字が存在します。

「セパレータ、スペース」カテゴリのUnicode文字

ypercubeᵀᴹの答え のwhere句を次のように拡張します。
(編集:文字列の先頭に\を追加します]

where name !~ '[\u0020\u00A0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202f\u205f\u3000]'

キャラクター:

u0020 SPACE
u00A0 NO-BREAK SPACE
u1680 OGHAM SPACE MARK
u2000 EN QUAD
u2001 EM QUAD
U2002 EN SPACE
u2003 EM SPACE
u2004 THREE-PER-EM SPACE
u2005 FOUR-PER-EM SPACE
u2006 SIX-PER-EM SPACE
u2007 FIGURE SPACE
u2008 PUNCTUATION SPACE
u2009 THIN SPACE
u200A HAIR SPACE
u202f NARROW NO-BREAK SPACE
u205f MEDIUM MATHEMATICAL SPACE
u3000 IDEGRAPHIC SPACE

....テストして、もう一度テストします。

5

私はwhere not (name ~ '[[:space:]]')'を試しましたが、上記と同じバイトシーケンス\x4a41534f4ec2a0424c414b45で「JASON BLAKE」を返しています。

バイトシーケンスがUTF8であると仮定します。

SELECT
  string,
  string NOT LIKE '% %' AS simple,
  string ~ '^\S*$' AS regexp_oppr,
  string !~ '[[:space:]]' AS regexp_oppr_posix
FROM ( VALUES
  ('THIS HAS A SPACE IN THE MIDDLE'),
  ('   BEFORE'),
  ('AFTER    '),
  ('NONE_NONE_NONE'),
  (' | JASON FALKNER'),
  (convert_from('\x4a41534f4ec2a0424c414b45'::bytea, 'UTF8'))
) AS t(string);

これはこれを出力します

             string             | simple | regexp_oppr | regexp_oppr_posix 
--------------------------------+--------+-------------+-------------------
 THIS HAS A SPACE IN THE MIDDLE | f      | f           | f
    BEFORE                      | f      | f           | f
 AFTER                          | f      | f           | f
 NONE_NONE_NONE                 | t      | t           | t
  | JASON FALKNER               | f      | f           | f
 JASON BLAKE                    | t      | t           | t
(6 rows)

JASON BLAKEがutf8であると仮定するのが正しかった場合、言及されたすべてのメソッドがその中のスペースを検出します(そして、私自身の追加である^\S*$のメソッド)。

1
Evan Carroll