This is the first part about posts what my “string_view support for regex” proposal entails. This part explains why I started to work on it, part 2 explains what it does for the user.

While working on toy project I wanted to parse the command line input with several simple regexes. Using C++17 I thought it would be nice to ‘copy’ the input using a std::string_view.

void foo(std::string_view input) {
	std::regex re{"foo.*bar"};
	std::string i{input};
	std::smatch match;
	if (regex_match(i, match, re))
		std::cout << "Found " << match[0] << "\n";
}

It works, but obviously I was not happy with it. I used a std::string_view to avoid copying and as a result I needed to make a copy to use it in the regex. Using const std::string& for input would have been more efficient.

Luckily it is possible to use a std::string_view as input if you use iterators.

void foo(std::string_view input) {
	std::regex re{"foo.*bar"};
	std::match_results<std::string_view::const_iterator> match;
	if (regex_match(input.begin(), input.end(), match, re))
		std::cout << "Found " << match[0] << "\n";
}

It works, but the call to std::cout still copies the matched data to a std::string. But no problem that can also be solved. Since the code uses uniform initialization we need a static_cast since length() returns a difference_type. This type differs from std::string_view::size_type and narrowing is not allowed.

void foo(std::string_view input) {
	std::regex re{"foo.*bar"};
	std::match_results<std::string_view::const_iterator> match;
	if (regex_match(input.begin(), input.end(), match, re)) {
		std::string_view output{&*match[0].first,
		                        static_cast<size_t>(match[0].length())};
		std::cout << "Found " << output << "\n";
	}
}

So that will be the best we can do, hopefully in C++23 the following code will be as efficient at the previous example.

void foo(std::string_view input) {
	std::regex re{"foo.*bar"};
	std::svmatch match;
	if (regex_match(input, match, re))
		std::cout << "Found " << match[0] << "\n";
}

That looks a lot like the initial example, but the match is a svmatch, short for string_view match. The std::operator<< will automatically use the new view() member function of the std::sub_match.

I’m working on a paper which I hope will make it into C++23. The latest draft of the proposal is available. Part 2 will go into more details what this proposal does.