none
正規表現 予想外の文字列がついて返ってくる RRS feed

  • 質問

  • regex_replaceで文字列を置換すると、予想外の文字になって返されてしまいます。

    使用方法が間違っているのでしょうか。

    source code:

    #include <string>
    #include <regex>
    #include <iostream>
    
    int main(
      )
    {
      std::regex reg("^120-0046");
      std::string str("120-0046 aaa");
      std::cout << std::regex_replace(str, reg, "");
      return 0;
    }

    output:

    | aaa

    期待している結果:

     aaa

    環境:

    Visual Studio Community 2013 Update4

    他の環境でのテスト:

    ideonやweb上で、上記ソースを実行しますと、「|」という文字は表示されません。

    その他:

    VS 2013 Update4で、上記のコードをwstring/wregex/wcoutにすると、「|」という文字は表示されず、期待した動作になります。



    • 編集済み aquria 2015年1月29日 16:25
    2015年1月29日 16:23

回答

  • その点、回答から漏れていました。厳密には分かりませんが、UNIX系ですとEUC-JPやUTF-8を使い、shift-jisではないからではないでしょうか?

    …と言ってしまうとまるでWindowsやVisual C++の実装の問題のように受け取られるかもしれませんが、あくまでC++仕様上の問題としてstd::stringがマルチバイト文字に対応していない辺りが原因で発生する問題です。
    EUC-JPやUTF-8の場合、マルチバイト文字が必ず\x80~\xFFの範囲を使うためUS-ASCII部分に影響を与えません。偶然回避できているに過ぎません。実際、 "[あ-お]" のような正規表現は通らないのではと思います。

    • 回答としてマーク aquria 2015年1月31日 14:18
    2015年1月30日 15:09

すべての返信

  • std::regexはASCII以外には対応していません。そのため、文字コードそのままに解釈されます。'-'の文字はshift-jis表現で \x81\x7C であり、 '\x7C' はASCII上では '|' となってしまいます。

    std::wregexであればこのような問題は発生しません。

    2015年1月29日 23:12
  • そういうことなのですか。ありがとうございます。

    ideonなどweb上で問題ないのはなぜなのでしょうか。

    osまたはコンパイラの環境依存?ということなのでしょうか。

    2015年1月30日 14:09
  • その点、回答から漏れていました。厳密には分かりませんが、UNIX系ですとEUC-JPやUTF-8を使い、shift-jisではないからではないでしょうか?

    …と言ってしまうとまるでWindowsやVisual C++の実装の問題のように受け取られるかもしれませんが、あくまでC++仕様上の問題としてstd::stringがマルチバイト文字に対応していない辺りが原因で発生する問題です。
    EUC-JPやUTF-8の場合、マルチバイト文字が必ず\x80~\xFFの範囲を使うためUS-ASCII部分に影響を与えません。偶然回避できているに過ぎません。実際、 "[あ-お]" のような正規表現は通らないのではと思います。

    • 回答としてマーク aquria 2015年1月31日 14:18
    2015年1月30日 15:09