Home > front end >  regex_replace invalid open parenthesis
regex_replace invalid open parenthesis

Time:09-04

DEMO

#include <iostream>
#include <regex>    

int main() {
    
    std::wstring str = LR"(
        
           bst.enable_adb_access="1"
           
           )";
           
    std::wregex re(L"(?<=bst\\.enable_adb_access.*?)\\d ");
    
    str = std::regex_replace(str, re, L"0");
    std::wcout << str << std::endl;
}

error:

terminate called after throwing an instance of 'std::regex_error'
what(): Invalid special open parenthesis.

https://regex101.com/r/a33eFL/1

Whats wrong with the parenthesis?

CodePudding user response:

Well, this is one illustration why the plural of "regex" is "regrets"...

C accepts several flavours of regexes, but none of them seems to understand lookbehinds. Default modified ECMAScript flavour only accepts lookaheads. I'm not 100% sure about POSIX, awk and grep flavours, but none of them seems to have any lookarounds whatsoever.

Fortunately, you can get the same effect without lookarounds, using capturing group. I had to change format string rules to sed, because default ECMAScript rules allow for two-digit backreferences.

#include <iostream>
#include <regex>    

int main() {
    
    std::wstring str = LR"(
        
           bst.enable_adb_access="1"
           
           )";
           
    std::wregex re(L"(bst\\.enable_adb_access.*?)\\d ");
    
    str = std::regex_replace(str, re, L"\\10", std::regex_constants::format_sed);
    std::wcout << str << std::endl;
}

See it online

CodePudding user response:

You don't need to use a lookbehind for this situation. Simply use a normal capturing group and include it in the replacement string:

#include <iostream>
#include <regex>    
 
using namespace std;
 
int main() {
    std::wstring str = LR"(
 
           bst.enable_adb_access="1"
 
           )";
 
    std::wregex re(L"(bst\\.enable_adb_access.*?)\\d ");
 
    str = std::regex_replace(str, re, L"$010");
    std::wcout << str << std::endl;
}

Output:

           bst.enable_adb_access="0"
 

Note that because the substitution for the capturing group is followed by a digit, we need to use the $nn format for the group number (hence $010), otherwise $10 could - dependent on the compiler - be interpreted as replacing with capture group 10.

Demo on ideone

  • Related