web-dev-qa-db-ja.com

文字列に英数字(またはスペース)のみが含まれているかどうかを判別する

文字列に英数字とスペースのみが含まれているかどうかを判別する関数を書いています。正規表現^[[:alnum:] ]+$と一致するかどうかを効果的にテストしていますが、正規表現は使用していません。これは私がこれまでに持っているものです:

#include <algorithm>

static inline bool is_not_alnum_space(char c)
{
    return !(isalpha(c) || isdigit(c) || (c == ' '));
}

bool string_is_valid(const std::string &str)
{
    return find_if(str.begin(), str.end(), is_not_alnum_space) == str.end();
}

より良い解決策、またはこれを行うための「よりC++」な方法はありますか?

27
dreamlax

私にはよく見えますが、isalphaisdigitの代わりにisalnum(c)を使用できます。

26
jopa

C++ 0xを楽しみにして、ラムダ関数を使用できるようになります(gcc 4.5またはVS2010でこれを試すことができます):

bool string_is_valid(const std::string &str)
{
    return find_if(str.begin(), str.end(), 
        [](char c) { return !(isalnum(c) || (c == ' ')); }) == str.end();
}
9

バインダーを使用してこれを行うこともできるので、ヘルパー関数をドロップできます。標準ライブラリバインダーよりもはるかに使いやすい Boost Binders をお勧めします。

bool string_is_valid(const std::string &str)
{
    return find_if(str.begin(), str.end(),
        !boost::bind(isalnum, _1) || boost::bind(std::not_equal_to<char>, _1, ' ')) == str.end();
}
2

マイナーポイントですが、is_not_alnum_space()を特定のコンパイルユニットでのみ表示されるヘルパー関数にしたい場合は、静的な名前空間ではなく、匿名の名前空間に配置する必要があります。

namespace {
bool is_not_alnum_space(char c)
{
    return !(isalpha(c) || isdigit(c) || (c == ' '));
}
}
...etc
1
Ilkka