none
文字列右の全角空白をトリムする方法 RRS feed

  • 質問

  • T-sqlのRTRIM関数は文字列右側の半角スペースは除外できますが、全角スペースが除外できません。
    全角スペースを半角に置き換えてRTRIMしてから半角スペースを全角スペースに置き換える
    方法はありますが、これだと文字の間に意識的に入れてある半角スペースまで置き換えて
    内容を改ざんしてしまうことになります。あくまでも文字列の末尾にある全角スペースと
    半角スペースを除外したいのです。
    何か良い方法は無いでしょうか?

    SQL Server2005 + T-sql
    2010年2月18日 6:27

回答

  • それっぽい結果になったのが下の書き方です。
    ([nvc] は nvarchar型の項目です。ちゃんと検証できていないかもしれません。悪しからず。。)

    SELECT '['+replace(replace(rtrim(replace(replace([nvc] COLLATE Japanese_BIN, CHAR(32), N'ありえない文字列'), N' ', CHAR(32))), CHAR(32), N' '), N'ありえない文字列', CHAR(32))+']' from [A]

    「N' '」は全角空白です。

    # 長いなあ。。。欲しいのはもっと簡単な書き方ですよね。

    いったん半角空白(CHAR(32))を適当な文字列に置換してから、全角空白を置換しています。(戻さなくちゃいけないのでえらく長い文になってしまいます。)
    したがって、絶対に出現しない「ありえない文字列」を決めなくてはならないという条件付です。

    • 回答としてマーク Tosh1021jp 2010年2月18日 9:31
    2010年2月18日 8:40

すべての返信

  • こんなんじゃだめでしょうか?
    SET @val = ' a b c     '  -- 末尾に半角、全角を含む文字列
    SET @Val = RTRIM(REPLACE(@Val COLLATE Japanese_BIN, ' ', '  '))
    2010年2月18日 8:18
  • ご回答ありがとうございます。

    >> SET @Val = RTRIM(REPLACE(@Val COLLATE Japanese_BIN, ' ', '  '))

    ’’で囲んでいるのは、1つ目は全角スペース
    2番目は半角スペースということでしょうか?

    これだと、 「ABC DEF    」のような文字列の場合 CとDの間の全角スペースも
    半角スペースに置き換わってしまいます。
    残念ながら要件を満たしておりません。

    2010年2月18日 8:34
  • それっぽい結果になったのが下の書き方です。
    ([nvc] は nvarchar型の項目です。ちゃんと検証できていないかもしれません。悪しからず。。)

    SELECT '['+replace(replace(rtrim(replace(replace([nvc] COLLATE Japanese_BIN, CHAR(32), N'ありえない文字列'), N' ', CHAR(32))), CHAR(32), N' '), N'ありえない文字列', CHAR(32))+']' from [A]

    「N' '」は全角空白です。

    # 長いなあ。。。欲しいのはもっと簡単な書き方ですよね。

    いったん半角空白(CHAR(32))を適当な文字列に置換してから、全角空白を置換しています。(戻さなくちゃいけないのでえらく長い文になってしまいます。)
    したがって、絶対に出現しない「ありえない文字列」を決めなくてはならないという条件付です。

    • 回答としてマーク Tosh1021jp 2010年2月18日 9:31
    2010年2月18日 8:40
  • ’’で囲んでいるのは、1つ目は全角スペース
    2番目は半角スペースということでしょうか?

    2番目は半角スペースが「2つ」です。

    ごめんなさい。詰めが甘かったですね。
    こんな感じでいかたでしょうか?

    DECLARE @Val NVARCHAR(255)
    SET @Val ='ABC DEF    '

    SET @Val = REPLACE(RTRIM(REPLACE(@Val COLLATE Japanese_BIN, ' ', '  ')) COLLATE Japanese_BIN, '  ', ' ')

    print '|'+@Val+'|'

    *** 結果 ***
    |ABC DEF|


    うーん、だめですかね?
    2010年2月18日 9:10
  • ご回答ありがとうございます。
    ちょっと長いのでFunctionにして使います。

    Microsoftが素直に対応してくれれば問題ないんですけどね。
    2010年2月18日 9:34
  • ご回答ありがとうございます。

    こちらも参考にさせていただきます。

    2010年2月18日 9:47
  • SELECT '['+replace(replace(rtrim(replace(replace([nvc] COLLATE Japanese_BIN, CHAR(32), N'ありえない文字列'), N' ', CHAR(32))), CHAR(32), N' '), N'ありえない文字列', CHAR(32))+']' from [A]

    「N' '」は全角空白です。
    どのような文字列が現れるかによっては、もうちょっと問題はやっかいかもしれません。私もうまい方法を思い付かないのですが、例えば末尾に全角スペースと半角スペースがいくつか連続して存在しているとうまくいきません。patindexがもうちょっと正規表現っぽいパターンが使えると良いのですが・・・。
    やっぱり関数化するしかないかな・・・?


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2010年2月18日 10:49
  • > 例えば末尾に全角スペースと半角スペースがいくつか連続して存在しているとうまくいきません。

    あっ、そうですね
    例えば末尾に全角スペース、半角スペース、全角スペースの並びだと(たとえ rtrim をもうひとつ被せても)うまくいかないと。。
    要求は「末尾にある全角スペースと半角スペースを除外したい」なので考慮漏れでした。
    ご指摘ありがとうございました。
    2010年2月18日 11:19
  • kobadesu様の式を参考にさせて頂き、LEFT を使ってみました。

    SET @val = LEFT(@val, LEN(RTRIM(REPLACE(@val COLLATE Japanese_BIN, ' ', CHAR(32))))) 

    全角→半角スペースに変換後、TRIM して LEN を取得。元の val から LEFT で取り出しています。

    ↓テストスクリプトはこれです、、、
    DECLARE @val as nvarchar(50)
    SET @val = N' a b c     '
    select '前['+@val+']' --検証用
    select '前['+REPLACE(@val COLLATE Japanese_BIN, CHAR(32), '@')+']' --検証用(半角スペース→@に変換)
    SET @val = LEFT(@val, LEN(RTRIM(REPLACE(@val COLLATE Japanese_BIN, ' ', CHAR(32)))))
    select '後['+@val+']' --検証用
    select '後['+REPLACE(@val COLLATE Japanese_BIN, CHAR(32), '@')+']' --検証用(半角スペース→@に変換)

    前[ a b c     ]
    前[@a b@c @@  ]
    後[ a b c]
    後[@a b@c]

    # これも考慮漏れがあるかどうかわかりにくいような。。
    • 編集済み anningo 2010年2月18日 12:08 説明追加(半角スペース→@に変換)
    • 回答の候補に設定 高橋 春樹 2010年2月19日 1:55
    2010年2月18日 12:06
  • なるほど。良さそうですね。大変参考になりました。
    私は最初、PATINDEXで末尾の半角スペースおよび全角スペースを取った位置を探し、それをLEFTで取り出そうとしていました。orz


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2010年2月19日 3:51
  • trapemiya様 高橋 春樹様
    確認ありがとうございました。
    じつは trapemiya様が書かれた「PATINDEX」というキーワードから先ほどの式に辿り着いた次第です。
    # 力を合わせてより良い答えに近づけるという、フォーラムの良さですね(v v)
    2010年2月19日 4:26