I'd like to check if it match the following format:
(integer,integer), including the parenthesis and the commas. For example:for (3,4) would return true and for (6.4 would return false
I tried with
string input;
regex check("(\\-|+)?[[:d:]]+,?(\\-|+)?[[:d:]]+");
cin >> input;
if (regex_match(input, check)) cout << "okay" << endl;
else cout << "error";
but I'm getting runtime error
It seems you are looking for
regex check(R"(\([-+]?\d+,[-+]?\d+\))")
This defines a pattern like ^\([-+]?\d+,[-+]?\d+\)$ when used with std::regex_match that requires a full string match.
Details:
^ - start of string (implicit in regex_match)
\( - a (
[-+]? - 1 or 0 + or - chars
\d+ - 1 or more digits
, - a comma
[-+]? - 1 or 0 + or - chars
\d+ - 1 or more digits
\) - a )
$ - end of string (implicit in regex_match)
C++ demo:
regex check(R"(\([-+]?\d+,[-+]?\d+\))");
string s1("(44,45)");
string s2("(44,45");
smatch match;
if (regex_match(s1, match, check)) {
cout << s1 << ": Matched!" << endl;
} else {
cout << s1 << ": Not matched!" << endl;
}
if (regex_match(s2, match, check)) {
cout << s2 << ": Matched!" << endl;
} else {
cout << s2 << ": Not matched!" << endl;
}
Output:
(44,45): Matched!
(44,45: Not matched!
Try input this regex \(\d{1,},\d{1,}\)
Maybe it might works
Related
how to extract digit number value?
std::regex legit_command("^\\([A-Z]+[0-9]+\\-[A-Z]+[0-9]+\\)$");
std::string input;
let say the user key in
(AA11-BB22)
i want get the
first_character = "aa"
first_number = 11
secondt_character = "bb"
second_number = 22
You could use capture groups. In the example below I replaced (AA11+BB22) with (AA11-BB22) to match the regex you posted. Note that regex_match only succeeds if the entire string matches the pattern so the beginning/end of line assertions (^ and $) are not required.
#include <iostream>
#include <regex>
#include <string>
using namespace std;
int main() {
const string input = "(AA11-BB22)";
const regex legit_command("\\(([A-Z]+)([0-9]+)-([A-Z]+)([0-9]+)\\)");
smatch matches;
if(regex_match(input, matches, legit_command)) {
cout << "first_character " << matches[1] << endl;
cout << "first_number " << matches[2] << endl;
cout << "second_character " << matches[3] << endl;
cout << "second_number " << matches[4] << endl;
}
}
Output:
$ c++ main.cpp && ./a.out
first_character AA
first_number 11
second_character BB
second_number 22
im new to Regex and C++.
My problem is, that '=' is matching when I search for [a-zA-Z]. But this is only a-z without '='?
Can anyone help me please?
string string1 = "s=s;";
enum states state = s1;
regex statement("[a-zA-Z]+[=][a-zA-Z0-9]+[;]");
regex rg_left_letter("[a-zA-Z]");
regex rg_equal("[=]");
regex rg_right_letter("[a-zA-Z0-9]");
regex rg_semicolon("[;]");
for (const auto &s : string1) {
cout << "Current Value: " << s << endl;
// step(&state, s);
if (regex_search(&s, rg_left_letter)) {
cout << "matching: " << s << endl;
} else {
cout << "not matching: " << s << endl;
}
// cout << "Step Executed with sate: " << state << endl;
}
This outputs:
Current Value: s
matching: s
Current Value: =
matching: =
Current Value: s
matching: s
Current Value: ;
not matching: ;
When you write
regex_search(&s, rg_left_letter)
you basically search the C-String &s for a match character-wise, beginning at the character s. Therefore, your loop will search for a match in the remaining sub-strings
s=s;
=s;
s;
;
Which will always succeed, except in the last case, as there is always one character in the entire string that fits your regex. Note however that this assumes that std::string has some 0-termination added, which is, as far as I can tell, not guaranteed if you do not explicitely use the c_str() method, making your code UB.
What you really want to use is the function regex_match, together with your original regex just as simple as:
#include <iostream>
#include <regex>
int main()
{
std::regex statement("[a-zA-Z]+[=][a-zA-Z0-9]+[;]");
if(std::regex_match("s=s;", statement)) { std::cout << "Hooray!\n"; }
}
This is working for me:
int main(void) {
string string1 = "s=s;";
enum states state = s1;
regex statement("[a-zA-Z]+[=][a-zA-Z0-9]+[;]");
regex rg_left_letter("[a-zA-Z]");
regex rg_equal("[=]");
regex rg_right_letter("[a-zA-Z0-9]");
regex rg_semicolon("[;]");
//for (const auto &s : string1) {
for (int i = 0; i < string1.size(); i++) {
cout << "Current Value: " << string1[i] << endl;
// step(&state, s);
if (regex_match(string1.substr(i, 1), rg_left_letter)) {
cout << "matching: " << string1[i] << endl;
} else {
cout << "not matching: " << string1[i] << endl;
}
// cout << "Step Executed with sate: " << state << endl;
}
cout << endl;
return 0;
}
If the input is
11100011100000011
the largest sequence of 0's is at
000000 (pos: 9)
I tried
regex re0("(.*)([0]+)(.*)");
regex_search(sch, m, re0);
for (unsigned i = 0; i<m.size(); ++i) {
std::cout << "match " << i << " (" << m[i] << ") ";
std::cout << "at position " << m.position(i) << std::endl;
}
But it gives my wrong results
11100011100000011
match 0 (11100011100000011) at position 0
match 1 (11100011100000) at position 0
match 2 (0) at position 14
match 3 (11) at position 15
How do you make the [0]+ greedy to find the largest match?
The longest series of zeros is that that is not followed (not necessarily immediately) by at least the same sequence of zeros:
(0+)(?!.*\1)
Regex demo: https://regex101.com/r/G0FieA/2
C++:
regex re0("(0+)(?!.*\\1)");
if (regex_search(sch, m, re0)) {
std::cout << "match '" << m[0] << "' ";
std::cout << "at position " << m.position(0) << std::endl;
}
Full demo: https://ideone.com/PnFrMq
I am trying to extract values from myString1 using std::stringstream like shown below:
// Example program
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main()
{
string myString1 = "+50years";
string myString2 = "+50years-4months+3weeks+5minutes";
stringstream ss (myString1);
char mathOperator;
int value;
string timeUnit;
ss >> mathOperator >> value >> timeUnit;
cout << "mathOperator: " << mathOperator << endl;
cout << "value: " << value << endl;
cout << "timeUnit: " << timeUnit << endl;
}
Output:
mathOperator: +
value: 50
timeUnit: years
In the output you can see me successfully extract the values I need, the math operator, the value and the time unit.
Is there a way to do the same with myString2? Perhaps in a loop? I can extract the math operator, the value, but the time unit simply extracts everything else, and I cannot think of a way to get around that. Much appreciated.
The problem is that timeUnit is a string, so >> will extract anything until the first space, which you haven't in your string.
Alternatives:
you could extract parts using getline(), which extracts strings until it finds a separator. Unfortunately, you don't have one potential separator, but 2 (+ and -).
you could opt for using regex directly on the string
you could finally split the strings using find_first_of() and substr().
As an illustration, here the example with regex:
regex rg("([\\+-][0-9]+[A-Za-z]+)", regex::extended);
smatch sm;
while (regex_search(myString2, sm, rg)) {
cout <<"Found:"<<sm[0]<<endl;
myString2 = sm.suffix().str();
//... process sstring sm[0]
}
Here a live demo applying your code to extract ALL the elements.
You could something more robust like <regex> like in the example below:
#include <iostream>
#include <regex>
#include <string>
int main () {
std::regex e ("(\\+|\\-)((\\d)+)(years|months|weeks|minutes|seconds)");
std::string str("+50years-4months+3weeks+5minutes");
std::sregex_iterator next(str.begin(), str.end(), e);
std::sregex_iterator end;
while (next != end) {
std::smatch match = *next;
std::cout << "Expression: " << match.str() << "\n";
std::cout << " mathOperator : " << match[1] << std::endl;
std::cout << " value : " << match[2] << std::endl;
std::cout << " timeUnit : " << match[4] << std::endl;
++next;
}
}
Output:
Expression: +50years
mathOperator : +
value : 50
timeUnit : years
Expression: -4months
mathOperator : -
value : 4
timeUnit : months
Expression: +3weeks
mathOperator : +
value : 3
timeUnit : weeks
Expression: +5minutes
mathOperator : +
value : 5
timeUnit : minutes
LIVE DEMO
I'd use getline for the timeUnit, but since getline can take only one delimiter, I'd search the string separately for mathOperator and use that:
string myString2 = "+50years-4months+3weeks+5minutes";
stringstream ss (myString2);
size_t pos=0;
ss >> mathOperator;
do
{
cout << "mathOperator: " << mathOperator << endl;
ss >> value;
cout << "value: " << value << endl;
pos = myString2.find_first_of("+-", pos+1);
mathOperator = myString2[pos];
getline(ss, timeUnit, mathOperator);
cout << "timeUnit: " << timeUnit << endl;
}
while(pos!=string::npos);
std::string str = "ahw \t\n";
std::regex re(R"((\s)*)");
std::smatch mr;
if (std::regex_search(str, mr, re))
{
std::cout << "match found: " << mr.size() << "\n";
for (size_t i = 0; i < mr.size(); ++i)
{
std::string strrep = mr.str(i);
int len = mr.length(i);
std::cout << "index: " << i << "len : " << len << " string: '" << strrep << "'\n";
}
}
std::string newStr = std::regex_replace(str, re, "");
std::cout << "new string: '" << newStr << "'\n";
result:
What I expect: only 1 match, strrep should be ' \t\n', and len should be len(strrep) = 6. But both vc12 and gcc4.9.2 show the above result.
What's wrong with my understand? How could I match the whitespace sequence ' \t\n'?
Just turn \s* to \s+ in your regex because \s* matches an empty string also(ie, \s* matches zero or more spaces) also and you don't need to have a capturing group.