【问题标题】:Determine if a string contains only alphanumeric characters (or a space)确定字符串是否仅包含字母数字字符(或空格)
【发布时间】:2011-02-24 23:51:26
【问题描述】:

我正在编写一个函数来确定字符串是否仅包含字母数字字符和空格。我正在有效地测试它是否匹配正则表达式 ^[[: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++”的方式来做到这一点?

【问题讨论】:

  • 我看不出有什么不是 C++ 的。你介意告诉我们吗?
  • @Mads:你看,我不确定它是否足够 C++!我来自 C 背景,每次我提出问题并提供“太 C 而 C++ 不足”的代码时,我都会被谋杀。
  • 那么,谋杀回来。至少这段代码没有错。 C++ 是一种多范式语言,没有一种风格比其他风格更正确。任何试图以不同方式告诉你的人,都不知道他们在说什么。如果您喜欢元编程,请使用模板。如果您喜欢过程式编程,请使用函数重载等基本功能。如果您喜欢 OO 代码,请使用继承。或者混搭。
  • 但请务必使用 RAII,而不是显式管理资源并将自己暴露在泄漏中。
  • 我也想避免双重否定:使用find_if_not并将函数重命名为is_alnum_space并删除返回的!

标签: c++ string iterator


【解决方案1】:

在我看来不错,但您可以使用 isalnum(c) 代替 isalphaisdigit

【讨论】:

  • +1。如果您想计算其他类型的空格(例如制表符),也可以使用isspace()
  • 我对改进的唯一建议是在函数名中不要包含_not_,因为它会导致代码不可读。考虑一下这个:return find_if(str.begin(), str.end(), is_alnum_space) != str.end();
  • @Johnsyweb:但这行不通。这将为包含 至少一个 字母数字+空格字符的字符串返回 true,但我想确保它们是 all 字母数字+空格字符。 find_if 的目的是找到满足谓词的第一个元素,谓词“不是字母数字或空格”。如果我们得到str.end(),我们知道没有字符满足该谓词,所以它们必须都是字母数字或空格字符。
  • @dreamlax:你是对的。这显然是漫长的一周:-)
  • @Johnsyweb 如果您希望它更具可读性,请改用 find_if_not ;)
【解决方案2】:

期待 C++0x,你将能够使用 lambda 函数(你可以在 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();
}

【讨论】:

  • 语法一开始很混乱,但我相信我会习惯的。
  • 完美!非常感谢!! +1!
  • 只需在输入时将“?”传递给函数,它会在 C++ 运行时级别(至少是 MS 运行时)立即抛出。
  • 从字面上看,似乎有一个断言检查字节是否高于 0...大声笑?直接在 isalnum() 和 isctype.cpp 使用的 isctype.cpp 中,该文件的调试数据甚至无法从 MS 调试服务器获得。
【解决方案3】:

您也可以使用活页夹来执行此操作,这样您就可以删除辅助函数。我推荐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();
}

【讨论】:

  • 哇,既疯狂又酷。虽然,我不检查所有类型的空格,我只想检查空格字符本身。用活页夹还可以吗?
  • @dreamlax - 是的,这是可能的。我已经更新了答案。
【解决方案4】:

小问题,但如果您希望 is_not_alnum_space() 成为仅在该特定编译单元中可见的辅助函数,则应将其放在匿名命名空间中,而不是使其成为静态:

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

【讨论】:

  • 感谢您的建议,与使用静态函数相比,这种匿名命名空间有什么好处?
  • 当前的 c++ 标准已弃用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-05
  • 1970-01-01
  • 2015-06-09
  • 1970-01-01
  • 1970-01-01
  • 2010-10-19
  • 2014-11-01
相关资源
最近更新 更多