【问题标题】:How to check if a string is all lowercase and alphanumerics?如何检查字符串是否全部为小写字母和数字?
【发布时间】:2012-07-03 10:00:57
【问题描述】:

是否有检查这些情况的方法?或者我是否需要解析字符串中的每个字母,并检查它是否是小写(字母)并且是数字/字母?

【问题讨论】:

    标签: c++ string lowercase alphanumeric


    【解决方案1】:

    您可以使用islower()isalnum() 来检查每个字符的这些条件。没有字符串级别的函数可以执行此操作,因此您必须自己编写。

    【讨论】:

    • 好点。我已经对此进行了编辑以反映这一点。我不知道那个功能。
    • 这里有点困惑,您用“好点...”评论了自己的答案
    • @t0mm13b 在我发表之前有一条评论指出 isalnum()。我猜它已被删除:P
    • 不..您仍然需要在发布问题后等待 x 分钟才能接受答案,但谢谢
    • @Oleksi:我对你的被接受非常满意——尽管该功能确实存在,但我不确定我是否会推荐使用它。我很确定大多数人会在循环中找到类似 islowerisalnum 或传递给 std::find 的东西更容易理解。
    【解决方案2】:

    假设“C”语言环境是可接受的(或为criteria 换成不同的字符集),请使用find_first_not_of()

    #include <string>
    
    bool testString(const std::string& str)
    {
          std::string criteria("abcdefghijklmnopqrstuvwxyz0123456789");
          return (std::string::npos == str.find_first_not_of(criteria);
    }
    

    【讨论】:

    • 假定“C”语言环境(这对 OP 可能无关紧要)。
    • @bgporter 很抱歉将近两年后才回复,但是这种方法效率如何?我正在研究化学方程式平衡器,这似乎是一个理想的预检查,而不是对每个字符执行多次检查。
    • 我猜这个问题是“与什么相比有效率?”。我的第一选择是假设标准库通常比手写代码足够快(并且相对没有错误)。
    • @Andrue 效率不会很高,因为std::find_first_not_of 需要一个内部循环来检查元素是否不在集合中,这与isdigitisalnumislower 不同可以根据区域设置仅使用一些比较
    【解决方案3】:

    您可以使用 tolower & strcmp 来比较 original_string 和 tolowered 的字符串。然后每个字符单独计算数字。

    (OR) 对每个字符执行以下操作。

    #include <algorithm>
    
    static inline bool is_not_alphanum_lower(char c)
    {
        return (!isalnum(c) || !islower(c));
    }
    
    bool string_is_valid(const std::string &str)
    {
        return find_if(str.begin(), str.end(), is_not_alphanum_lower) == str.end();
    }
    

    我使用了以下信息: Determine if a string contains only alphanumeric characters (or a space)

    【讨论】:

      【解决方案4】:

      如果您的字符串包含 ASCII 编码的文本并且您喜欢编写自己的函数(就像我一样),那么您可以使用这个:

      bool is_lower_alphanumeric(const string& txt)
      {
        for(char c : txt)
        {
          if (!((c >= '0' and c <= '9') or (c >= 'a' and c <= 'z'))) return false;
        }
        return true;
      }
      

      【讨论】:

        【解决方案5】:

        这不是很为人所知,但语言环境实际上确实具有一次确定整个字符串的特征的功能。具体来说,语言环境的ctype facet 有一个scan_is 和一个scan_not,用于扫描适合指定掩码(字母、数字、字母数字、小写字母、大写字母、标点符号、空格、十六进制数字等)的第一个字符.),或者第一个不适合的,分别。除此之外,它们的工作方式有点像std::find_if,返回作为“结束”传递的任何内容以表示失败,否则返回指向字符串中不符合您要求的第一项的指针。

        这是一个简单的示例:

        #include <locale>
        #include <iostream>
        #include <iomanip>
        
        int main() {
        
            std::string inputs[] = { 
                "alllower",
                "1234",
                "lower132",
                "including a space"
            };
        
            // We'll use the "classic" (C) locale, but this works with any
            std::locale loc(std::locale::classic());
        
            // A mask specifying the characters to search for:          
            std::ctype_base::mask m = std::ctype_base::lower | std::ctype_base::digit;
        
            for (int i=0; i<4; i++) {
                char const *pos;
                char const *b = &*inputs[i].begin();
                char const *e = &*inputs[i].end();
        
                std::cout << "Input: " << std::setw(20) << inputs[i] << ":\t";
        
                // finally, call the actual function:
                if ((pos=std::use_facet<std::ctype<char> >(loc).scan_not(m, b, e)) == e)
                    std::cout << "All characters match mask\n";
                else
                    std::cout << "First non-matching character = \"" << *pos << "\"\n";
            }
            return 0;
        }
        

        我怀疑大多数人会更喜欢使用std::find_if,尽管使用它几乎相同,但是可以很容易地推广到更多情况。尽管它的适用性要窄得多,但对用户来说并不是很容易(尽管我想如果你正在扫描 large 块文本,它可能至少会快一点)。

        【讨论】:

          【解决方案6】:

          只需使用std::all_of

          bool lowerAlnum = std::all_of(str.cbegin(), str.cend(), [](const char c){
              return isdigit(c) || islower(c);
          });
          

          如果您不关心语言环境(即输入是纯 7 位 ASCII),则可以将条件优化为

          [](const char c){ return ('0' <= c && c <= '9') || ('a' <= c && c <= 'z'); }
          

          【讨论】:

            猜你喜欢
            • 2018-02-03
            • 2012-02-06
            • 1970-01-01
            • 1970-01-01
            • 2017-03-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-02-08
            相关资源
            最近更新 更多