开发者

Check if string contains a range of numbers

I'd like to test a std::string for containing numbers of any range e.g 5 to 35 in a std::st开发者_开发技巧ring s = "XDGHYH20YFYFFY" would there be function or I would have to convert a number to string and then use a loop to find each one?


I'd probably use a locale that treated everything except digits as white-space, and read the numbers from a stringstream imbued with that locale and check if they're in range:

#include <iostream>
#include <algorithm>
#include <locale>
#include <vector>
#include <sstream>

struct digits_only: std::ctype<char> 
{
    digits_only(): std::ctype<char>(get_table()) {}

    static std::ctype_base::mask const* get_table()
    {
        static std::vector<std::ctype_base::mask> 
            rc(std::ctype<char>::table_size,std::ctype_base::space);

        std::fill(&rc['0'], &rc['9'], std::ctype_base::digit);
        return &rc[0];
    }
};

bool in_range(int lower, int upper, std::string const &input) { 
    std::istringstream buffer(input);
    buffer.imbue(std::locale(std::locale(), new digits_only()));

    int n;

    while (buffer>>n)
        if (n < lower || upper < n)
            return false;
    return true;
}

int main() {
    std::cout << std::boolalpha << in_range(5, 35, "XDGHYH20YFYFFY");
    return 0;
}


As much as some people are going to immediately go to regex on this, I think your best bet is actually a hybrid solution. Use REGEX to find numbers, then parse them and see if they're in range.

Something like this in C#. Not sure what regex libraries are available to you in C++.

using System.Text.RegularExpressions.Regex;
using System.Text.RegularExpressions.Match;
using System.Text.RegularExpressions.MatchCollection;

private static const Regex NUMBER_REGEX = new Regex(@"\d+")

public static bool ContainsNumberInRange(string str, int min, int max)
{
    MatchCollection matches = NUMBER_REGEX.Matches(str);
    foreach(Match match in matches)
    {
        int value = Convert.ToInt32(match.Value);
        if (value >= min && value <= max)
            return true;
    }

    return false;
}


If you are searching for all of the numbers in the range then use string::find function in a loop. Here is the reference for the function:

http://www.cplusplus.com/reference/string/string/find/

Also do you want to use the numbers in the string only once? For example SDFSD256fdsfs will give you the numbers 2 5 6 25 56 256 if you don't remove them from the string after each match.


You can do this iteratively with a stringstream object.

#include <iostream>
#include <string>
#include <sstream>
#include <cctype>

void check (std::string& s) {
    std::stringstream ss(s);

    std::cout << "Searching string: " << s << std::endl;
    while (ss) {

        while (ss && !isdigit(ss.peek ()))
            ss.get ();

        if (! ss)
            break;

        int i = 0;
        ss >> i;
        std::cout << "  Extraced value: " << i << std::endl;

    }
}


int main () {

    std::string s1 = "XDGHYH20YFYFFY";
    std::string s2 = "20YF35YFFY100";
    check (s1);
    check (s2);
    return 0;
}

Yields:

Searching string: XDGHYH20YFYFFY
  Extraced value: 20
Searching string: 20YF35YFFY100
  Extraced value: 20
  Extraced value: 35
  Extraced value: 100

Adding parameters to the check function to limit the results accepted would be trivial.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜