Dion
Dion

Reputation: 55

Qt QRegExp: replace spaces in a quoted string

There is a line example:

text a b c text "text text1 text2" text d e f

I need to replace all spaces that are inside quotes. This can be solved with simpler string operations, but I would like to solve it with QRegExp (Qt 5).

After processing, I want to get a result like this

text a b c text "text_text1_text2" text d e f

C++ code with Qt:

QString str = QString("text a b c text \"text text1 text2\" text d e f");
qDebug() << str.replace(QRegExp("\"(.+)\""), QString("_"));

The pattern correctly finds the quoted string, but replaces it entirely. How do I replace only spaces? I found a solution, but it is for JavaScript, can I adapt it for Qt?

str.replace(/"[^"]*"/g, match => match.replace(/ /g, "_"));

Thanks!

Upvotes: 1

Views: 186

Answers (1)

Pepijn Kramer
Pepijn Kramer

Reputation: 13075

I don't know Qt, but I do know regex from the standard library. And then it works like this. Probably there is a regex out there that can do it in one stage... didn't want to debug that :)

#include <string>
#include <regex>

std::string my_replace(const std::string& input)
{
    const std::regex rx{ "(.*?\\\")(.*)(\\\".*$)" }; // first expression to get everything between ""
    const std::regex ws{ "(\\s+)" }; // second expression for replace
    std::smatch rx_match;
    std::smatch ws_match;


    std::string retval{ input };
    if (std::regex_search(input, rx_match, rx))
    {
        // match[0] = whole string
        // match[1] = first group, everything before " including "
        // match[2] = second group, the part between ""
        // match[3] = last group, everyhting after second " including "
        auto mid_str = rx_match[2].str();
    
        // only replace stuff in the second group
        mid_str = std::regex_replace(mid_str, ws, "_");

        // stitch back together
        retval = rx_match[1].str() + mid_str + rx_match[3].str();
    }

    return retval;

}

int main()
{
    auto str = my_replace("text a b c text \"text text1 text2\" text d e f");
}   

Upvotes: 1

Related Questions