Help us understand the problem. What is going on with this article?

半角全角空白(スペース)トリミング

【序文】

SQLServer2017 で追加された TRIM関数
全角空白(任意の一文字)の削除にも対応している。

1> SELECT TRIM(N' ' FROM N'  令和元年');
2> GO

------
令和元年

(1 行処理されました)

少々違和感のある文法だけど。
しかしこの手の組み込みトリミング関数は半角空白にしか対応してない場合が多い。SQLServer で言えば、LTRIMRTRIM関数とか。
全角空白にも対応させる必要に迫られ関数を自作する局面も多いが、難しい処理ではない。
特に簡単な方法を取り上げる。

【環境】

SQLServer SQLCMD SSMS
2017 14.0.1000.169 v18.2

設定はデフォルト。
従って文字列の比較で半角・全角空白は区別されない。

【PATINDEX関数を利用する方法】

PATINDEX関数を利用すれば、半角・全角空白以外の文字が最初に現れる先頭位置を求めることができる。
後はその文字数分削除すれば良い。
ループで回し、先頭から一文字ずつ自力で調べて……といった冗長な実装を見かけることがあるが、そんな面倒なことをする必要はない。
実装例は以下。

DECLARE @str    NVARCHAR(MAX)   = N'   令和元年';                  -- 対象文字列(先頭に半角・全角空白)
DECLARE @cutLen INT             = PATINDEX(N'%[^ ]%', @str) - 1;   -- カットする先頭文字列数

SELECT
      @str                              [処理対象文字列]
    , @cutLen                           [カットする先頭文字列数]
    , RIGHT(@str, LEN(@str) - @cutLen)  [処理後文字列(RIGHT)]
    , STUFF(@str, 1, @cutLen, N'')      [処理後文字列(STUFF)]
;

N'   令和元年'+ ++令和元年 と半角・全角空白が先頭に含まれる。
N'%[^ ]%'^+ で半角・全角空白以外の意味。

実行結果は以下。

トリミング処理は RIGHT STUFF 関数のどちらでも良い。
パフォーマンスの差は未検証だが、誤差の範囲だろう。お好きな方を。
勿論、先頭に半角・全角空白が含まれないケースでもこのコードは正しく動作する。
また半角・全角空白が区別される環境でも、N'%[^ ]%' に全角空白を追記し、N'%[^  ]%' とすれば良い。
半角・全角が区別される環境については別投稿にまとめたのでそちら参照。

【自力で空白を調べるアルゴリズム】

関数化すれば以下の処理だけ書けば良い。トリミング対象文字列は引数で与えられるものとする。

1. 引数で与えられた文字列の先頭 1文字が空白以外の場合は処理を終了
2. 引数で与えられた文字列の先頭 1文字を削除し、それを引数に自分自身をコール

実装例は以下。

IF OBJECT_ID (N'dbo.LTrimEX', N'FN') IS NOT NULL
    DROP FUNCTION LTrimEX;
GO
-- 全角空白対応版 LTRIM
CREATE FUNCTION dbo.LTrimEX(@STR NVARCHAR(MAX))
RETURNS NVARCHAR(MAX)
AS
BEGIN
    IF LEFT(@STR, 1) = N' '                                 -- 先頭1文字が空白の場合
        SELECT @STR = dbo.LTrimEX(STUFF(@STR, 1, 1, N''));  -- 先頭1文字を削除し再帰呼び出し
    RETURN(@STR);
END;
GO

実行例は以下。

1> PRINT dbo.LTrimEX(N'   令和元年');
2> GO
令和元年

関数の中身はたった 3行。
簡単なアルゴリズムなので大抵のプログラミング言語にも移植できるだろう。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away