C++ std::regex not support look ahead backreference - c++

I want to match a rule, some name occur like ABA, And A must not equal B.
for example,
'allen_bob_allen' is valid.
'allen_allen_allen' is not valid.
at https://regexr.com/, I wrote the regex pattern
([a-z]+)_(?!\1)([a-z]+)_\1 and it work perfectly,
But When I write this in C++, use std::regex,
using namespace std;
#include <regex>
int main() {
std::regex regex_test2("([a-z]+)_(?<!\\1)([a-z]+)_\\1");
return 0;
}
I got the following error:
libc++abi.dylib: terminating with uncaught exception of type std::__1::regex_error: The expression contained an invalid back reference.
here is my compiler info:
Is there anyway to fix this?

Related

chrono literals in VS2015

The following code gives me a compile time error:
#include <chrono>
int main() {
auto day = 24h;
return 0;
}
Error C3688: invalid literal suffix 'h'; literal operator or literal operator template 'operator ""h' not found.
I'm trying this on Visual Studio 2015 Update 1, which according to this should work, so what's going on?
The literals aren't in the global namespace. Add this:
using namespace std::chrono_literals;
Depending on the situation, you might also consider using:
using std::chrono::operator""h;
instead of importing every name from that namespace if you need more fine grained control.

Why does the c++ regex_match function require the search string to be defined outside of the function?

I am using Visual Studio 2013 for development, which uses v12 of Microsoft's c++ compiler tools.
The following code executes fine, printing "foo" to the console:
#include <regex>
#include <iostream>
#include <string>
std::string get() {
return std::string("foo bar");
}
int main() {
std::smatch matches;
std::string s = get();
std::regex_match(s, matches, std::regex("^(foo).*"));
std::cout << matches[1] << std::endl;
}
// Works as expected.
The same code, with the string "s" substituted for the "get()" function, throws a "string iterators incompatible" error at runtime:
#include <regex>
#include <iostream>
#include <string>
std::string get() {
return std::string("foo bar");
}
int main() {
std::smatch matches;
std::regex_match(get(), matches, std::regex("^(foo).*"));
std::cout << matches[1] << std::endl;
}
// Debug Assertion Failed!
// Expression: string iterators incompatible
This makes no sense to me. Can anyone explain why this happens?
The reason is that get() returns a temporary string, so the match results contains iterators into an object that no longer exists, and trying to use them is undefined behaviour. The debugging assertions in the Visual Studio C++ library notice this problem and abort your program.
Originally C++11 did allow what you're trying to do, but because it is so dangerous it was prevented by adding a deleted overload of std::regex_match which gets used when trying to get match results from a temporary string, see LWG DR 2329. That means your program should not compile in C++14 (or in compilers that implement the DR in C++11 mode too). GCC does not yet implement the change yet, I'll fix that.

c++11 regex back references

I don't manage to use back references in regular expression in c++.
After trying more esoteric things, I tried this simple script on gcc 4.8.1:
#include <iostream>
#include <regex>
#include <string>
using namespace std;
int main() {
regex e("(..)\\1");
string s("aaaa");
if (regex_match(s,e))
cout << "match" << endl;
return 0;
}
but it produces a runtime error. I tried various flags in regex_constants like ECMAScript or grep but to no avail. What's wrong with this way of using back references in C++ regex engine?
Just to make sure I was not missing something trivial, I tried this in Java
class TestIt
{
public static void main (String[] args) throws java.lang.Exception
{
final String s = "aaaa";
final String e = "(..)\\1";
if (s.matches(e))
System.out.printf("match");
}
};
and obviously it prints match as expected, which is reassuring.
The regex engine included in gcc (in libstdc++) is not fully working yet. This regex works as expected on clang. So this issue has nothing to do with the way C++ treats regular expressions; rather it depends on the compiler used.

STL and Regular Expression

I'm trying to write a string parser that uses the standard library methods in C++. I want to parse out of an incoming string substrings that end with a newline or a ';'. I keep getting exceptions from the regex object that I create. My pattern is:
string pattern = "(.+[\\n\\r;])";
regex cmd_sep(pattern);
I've tried it with and without the regex_constants::extended or basic flags.
You'd better post your error message, if you are using boost library. It is possible you've missed boost::regex tag.
Try this
#include <boost/regex.hpp>
#include <string>
using namespace std;
int main ()
{
string pattern = "(.+[\\n\\r;])";
static const boost::regex cmd_sep(pattern);
return 0;
}

Strange Error in using template<class InputIterator> string (InputIterator begin, InputIterator end);

Given such a code segment:
#include <iostream>
#include <iterator>
#include <fstream>
#include <string>
using namespace std;
int main(){
ifstream file("1.txt");
string str((istream_iterator<char>(file)),istream_iterator<char>());
file.close();
cout<<str<<endl;
}
The code constructs a string from a file using istream_iterator.
Notice that the first parameter of string constructor is enclosed with a pair of parentheses. If I omit the parentheses, there will be an error. In VC++ 2008, a link error will come about. In G++, the code has a wrong output.
I feel very strange about the parentheses. What's the difference and why?
Without the "extra" parentheses, you get C++'s "most vexing parse" -- instead of defining an object named str with the two istream_iterators to specify its initializers, it's parsed as a declaration of a function named str that returns a string, and the "stuff" in parentheses specifies the types of parameters it takes.
It looks like one of the examples for "C++ most vexing parse" problem. Looks like compiler is interpreting the statement with () as a function declaration of function str which accepts two parameters. By adding () you are informing the compiler that it is an object and not part of function prototype signature.