Замена слов в строке, но игнорировать их в кавычках - PullRequest
3 голосов
/ 22 января 2020

Я заменяю слова в строке content этим l oop:

std::string content = "This is original. \"This is original\"";

while (content.find("original") != std::string::npos)
    content.replace(content.find("original"), 8, "replacement");

Есть ли простой способ не заменить «оригинал» на «замену», когда он заключен в кавычки?

Так, например.

Это оригинал. «Это оригинал»

Будет заменено на:

Это замена. «Это оригинал»

Вместо выключенного:

Это замена. «Это замена»

Ответы [ 3 ]

1 голос
/ 22 января 2020

Идея состоит в том, чтобы искать то, что стоит на первом месте, слово для замены или открывающие кавычки.

Если это открывающие кавычки, вы ищете закрывающие кавычки и продолжаете замену после них.

std::string::find позволяет указать начальную позицию поиска.

Результат может выглядеть примерно так:

#include <iostream>
#include <string>

std::string& replace_except_in_quotes(std::string& content, const std::string& original, const std::string& replacement)
{
    for(size_t pos = 0U; pos < content.size(); /*incremented in body*/)
    {
        size_t nextOriginal = content.find(original, pos);
        if(nextOriginal == std::string::npos)
        {
            break;// All occurences replaced
        }
        size_t nextQuote = content.find('\"', pos);
        bool skipQuotes = (nextQuote != std::string::npos) && (nextQuote < nextOriginal);
        if(skipQuotes)
        {
            nextQuote = content.find('\"', nextQuote + 1);
            if(nextQuote == std::string::npos)
            {
                break; // Missing closing quote
            }
            pos = nextQuote+1;
            continue;
        }

        // Actually replace original with replacement
        content.replace(nextOriginal, original.size(), replacement);
        pos += replacement.size() + 1;
    }
    return content;
}



int main() 
{
    using namespace std;

    string content = "this is original.\"this is original\"";
    cout << replace_except_in_quotes(content, "original", "replacement") << "\n\n";

    content += '\n' + content + '\n' + content + '\n' + content;
    cout << replace_except_in_quotes(content, "original", "replacement") << "\n\n";;
    return 0;
}

Вывод:

this is replacement."this is original"

this is replacement."this is original"
this is replacement."this is original"
this is replacement."this is original"
this is replacement."this is original"

Годболт: https://gcc.godbolt.org/z/oYq3sy

0 голосов
/ 22 января 2020

Хорошо, я написал код, который делает то, что я хотел.

std::string content = "This is original. \"This is original\"";

std::string temp, res;
    unsigned long n = content.length();
    bool instring = false;

    for(int i = 0; i < n; ++i)
    {
        temp = temp + content[i];
        if(content[i] == '\"' || n == i+1)
            {
                if(instring)
                    {
                        res = res + temp;
                        temp = "";
                    } else
                    {
                        while (temp.find("original") != std::string::npos)
    temp.replace(temp.find("original"), 8, "replacement");
                        }
                        res = res + temp;
                        temp = "";
                    }
                instring = !instring;
            }
    }
    content = res;

Спасибо за вашу помощь.

0 голосов
/ 22 января 2020

Быстрое исправление, но только для первого слова в кавычках, если у вас впереди то же слово, оно не заменит его.

Образец

#include <iostream>
#include <string>

using namespace std; //for sample purposes


int main() 
{
    string content = "this is original. \"this is original\"";
    cout << "Original: " << content << endl;
    while (content.find("original") != std::string::npos)
       if(content.find('"'))
           break;
    content.replace(content.find("original"), 8, "replacement");
    cout << "Replaced: " << content;
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...