简体   繁体   中英

c++ - Replace string with double quotes to a string with double quotes

I an writing this software the make my work on my website a little easier. I just put in a script and it will highlight the code for me with spans. It is getting there, but I have a problem. (I am currently working on highlighting UnityC#)

I want strings to be yellow, including the double quotation marks, but the way I try it now causes an infinite loop. I know I am doing something wrong with the quotation marks, but I can't figure out what that is. Please help me :)

The variable original is created by std::string original ((istreambuf_iterator<char>(currentFile)), istreambuf_iterator<char>()); , where currentFile is the script I load in

std::size_t pos = 0;
while(original.find("\"", pos) != std::string::npos)
{
    //find the first occurrence of the quote
    std::size_t found = original.find("\"", pos);
    if(found != std::string::npos)
    {
        //save the start position of the string
        std::size_t start_pos = found;
        //save the end position by searching for the next quotation mark
        std::size_t end_pos = original.find_first_of("\"", start_pos+1);
        //Calculate the size of the string
        std::size_t length = end_pos-start_pos;
        //Make a copy of the word without the quotation marks
        std::string originalWord = original.substr(start_pos+1, length-1);
        //Make the new word with span, original word(without the quotation marks) and add quotation marks around the word
        std::string newWord = std::string("<span class='yellow_code'>") + "\"" + originalWord + "\"" + "</span>";
        std::cout<<originalWord<<" : "<<newWord<<std::endl;
        //Replace the string WITH the quotation marks for the newWord
        original.replace(start_pos, length+1, newWord);
        //Set the position to after the string
        pos = end_pos+1;
    }
    else
    {
        pos = found+1;
    }
}

When I run this, it will cout: /dataValues.dat : <span class='yellow_code'>"/dataValues.dat"</span> infinite.

What is wrong?

Regards, Dani

The problem is here: pos = end_pos + 1; which can let your index before the string is it is shorter than your preamble.

Let us see what happens with your example:

  • originally original is bla..."/dataValues.dat"... and end_pos is pos + 16
  • after replacement you get bla...<span class='yellow_code'>"/dataValues.dat"</span>... end_pos has not changed and points to the first l of yellow!
  • on next search you find again the same quoted string...

You must add to end_pos the lengths of <span...> and </span> to make it point immediately after </span>

You are not adding the size of the start and end tags that you add to the string. Here is a example of how you can do it

std::string start_tag = "<span class='yellow_code'>";
std::string end_tag = "\"</span>";

std::size_t pos = 0;
while(original.find("\"", pos) != std::string::npos)
{
    std::size_t found = original.find("\"", pos);
    if(found != std::string::npos)
    {
        std::size_t start_pos = found;
        std::size_t end_pos = original.find_first_of("\"", start_pos+1);
        if (end_pos == std::string::npos) // If the number of quotation characters is odd you would get undefined behavior
            break;
        std::size_t length = end_pos - start_pos;
        std::string originalWord = original.substr(start_pos+1, length-1);
        std::string newWord = start_tag + "\"" + originalWord + end_tag; // CHANGED: Added the start and end tags as std::string
        std::cout<<originalWord<<" : "<<newWord<<std::endl;
        original.replace(start_pos, length+1, newWord);
        pos = end_pos + start_tag.size() + end_tag.size(); // CHANGED: Added the size of the two tags
    }
}

UPDATE

After looking at pos , found , and start_pos it seemed like two of them were redundant.

std::size_t start_pos = 0;
while((start_pos = original.find("\"", start_pos)) != std::string::npos)
{
    std::size_t end_pos = original.find_first_of("\"", start_pos+1);
    if (end_pos == std::string::npos) // If the number of quotation characters is odd you would get undefined behavior
        break;
    std::size_t length = end_pos-start_pos;
    std::string originalWord = original.substr(start_pos+1, length-1);
    std::string newWord = start_tag + "\"" + originalWord + end_tag; // CHANGED: Added the start and end tags as std::string
    std::cout << originalWord << " : " << newWord <<std::endl;
    original.replace(start_pos, length+1, newWord);
    start_pos = end_pos + start_tag.size() + end_tag.size(); // CHANGED: Added the size of the two tags
}

Try it online

您应该std::regex

text = std::regex_replace(text,std::regex("string to be replaced"),"string with it earlier should be replaced");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM