@ Поли Я бы подумал, что об этом, наверное, тоже просили С ++, но я не могу его найти
Майкл Мрозек
1
В этом вопросе есть тэг std, но, возможно, вас могут заинтересовать строковые алгоритмы boost, которые также включают в себя широкий выбор алгоритмов замены (inplace / copy, чувствительно к регистру / нечувствительно к регистру, replace first / last / all / n-th ).
Есть функция для поиска подстроки в строке ( find) и функция для замены определенного диапазона в строке другой строкой ( replace), так что вы можете комбинировать их, чтобы получить желаемый эффект:
Как бы это исправить, если бы в исходной строке было более одного экземпляра «$ name», и я хотел заменить их все.
Том Лиз
1
Почему нет fromи toпередается по constссылке? Что делает твоя функция, если fromее там нет? -1от меня за это.
2010 г.,
10
@sbi Исправлено, хотя вы могли бы сформулировать это как рекомендации, а не атаки - мне это просто не пришло в голову, я редко думаю об этом, constи если бы я написал такой служебный метод, я бы назвал его, только если бы знал замена действительна
Майкл Мрозек
10
@Michael: Хорошо, я превратил свой голос против в голосование против. Увольнение constигнорирует один из лучших инструментов C ++. Передача по constссылке должна быть режимом по умолчанию для параметров функции. (FTR, без const, вы не могли бы даже передавать строковые литералы в вашу функцию, потому что вы не можете привязать временные значения к не constссылкам. Поэтому функция даже не будет делать то, для чего она была написана.)
sbi
19
Это все еще единственное решение в 2018 году? Если так и любой комитет C ++ читает это, разберитесь. Это смущает. разделите (строка, строка) и замените (строка, строка), пожалуйста!
Я уверен, std::regex_replaceчто не принимает строку Qt.
BartoszKP
1
Ты прав. Когда это происходит, QString предоставляет метод replace, который принимает QRexExp, позволяя использовать собственный материал Qt. Но я думаю, что текущий ответ можно исправить, заменив stringна string.toStdString().
Том
1
Или просто изменив Stringна std::string, потому что вопрос не связан с Qt. Пожалуйста, подумайте об этом - я с удовольствием опишу ваш ответ позже.
BartoszKP
5
Необработанная строка позволяет писать R"(\$name)"вместо "\\$name".
Jarod42
2
Насколько это будет медленнее, чем поиск / замена без учета времени создания std :: regex?
jw_
18
std::stringесть replaceметод, это то, что вы ищете?
Ваш вызов subject.replace в ReplaceStringInPlace () действительно изменяет строку на месте?
Дамиан
Я кратко посмотрел на источник, и похоже, что он использует семантику перемещения, чтобы переместить переднюю часть старой строки на место, чтобы она не копировалась, но новая вставленная часть копируется в старую строку и хвост старой строки копируется в буфер с измененным размером старой строки. Возможно, строка расширяется настолько, что весь базовый буфер перераспределяется, но если вы замените 1 на 1, как в его примере, я думаю, что это произойдет «на месте» или без какого-либо копирования, но если вы расширите строку, только первая часть старой строки не копируется, и только возможно тогда.
Motes
6
Да, вы можете сделать это, но вы должны найти позицию первой строки с помощью элемента find () строки, а затем заменить его элементом replace ().
Если вы планируете использовать Стандартную библиотеку, вам действительно нужно получить экземпляр книги «Стандартная библиотека С ++», которая очень хорошо охватывает все эти вещи.
Он многократно вызывает, std::string::find()чтобы найти другие вхождения искомой строки, пока std::string::find()ничего не находит. Поскольку std::string::find()возвращает позицию совпадения, у нас нет проблемы аннулирования итераторов.
Вы могли бы обернуть это в функцию, но это решение в одну строку звучит приемлемо. Проблема в том, что это изменит только первый случай, вы можете зацикливаться на нем, но это также позволяет вам вставить несколько переменных в эту строку с одним и тем же token ( %s)
Понравился стиль, но обнаружил, что разные строки сбивают с толку ^^str.replace(str.find("%s"), string("%s").size(), "Something");
Paul Würtz
3
Если все строки являются std :: string, вы обнаружите странные проблемы с обрезкой символов при использовании, sizeof()потому что она предназначена для строк C, а не строк C ++. Исправление заключается в использовании .size()метода класса std::string.
wstring myString = L"Hello $$ this is an example. By $$.";
wstring search = L"$$";
wstring replace = L"Tom";for(int i = myString.find(search); i >=0; i = myString.find(search))
myString.replace(i, search.size(), replace);
Я только сейчас изучаю C ++, но редактируя часть ранее опубликованного кода, я бы, вероятно, использовал что-то вроде этого. Это дает вам возможность заменить 1 или несколько экземпляров, а также позволяет указать начальную точку.
Ответы:
Есть функция для поиска подстроки в строке (
find
) и функция для замены определенного диапазона в строке другой строкой (replace
), так что вы можете комбинировать их, чтобы получить желаемый эффект:В ответ на комментарий, я думаю,
replaceAll
будет выглядеть примерно так:источник
from
иto
передается поconst
ссылке? Что делает твоя функция, еслиfrom
ее там нет?-1
от меня за это.const
и если бы я написал такой служебный метод, я бы назвал его, только если бы знал замена действительнаconst
игнорирует один из лучших инструментов C ++. Передача поconst
ссылке должна быть режимом по умолчанию для параметров функции. (FTR, безconst
, вы не могли бы даже передавать строковые литералы в вашу функцию, потому что вы не можете привязать временные значения к неconst
ссылкам. Поэтому функция даже не будет делать то, для чего она была написана.)С C ++ 11 вы можете использовать
std::regex
так:Двойная обратная косая черта необходима для выхода из escape-символа.
источник
std::regex_replace
что не принимает строку Qt.string
наstring.toStdString()
.String
наstd::string
, потому что вопрос не связан с Qt. Пожалуйста, подумайте об этом - я с удовольствием опишу ваш ответ позже.R"(\$name)"
вместо"\\$name"
.std::string
естьreplace
метод, это то, что вы ищете?Вы можете попробовать:
Я не пробовал себя, просто прочитал документацию
find()
иreplace()
.источник
Чтобы получить новую строку, используйте это:
Если вам нужна производительность, вот оптимизированная функция, которая модифицирует входную строку, она не создает копию строки:
тесты:
Вывод:
источник
Да, вы можете сделать это, но вы должны найти позицию первой строки с помощью элемента find () строки, а затем заменить его элементом replace ().
Если вы планируете использовать Стандартную библиотеку, вам действительно нужно получить экземпляр книги «Стандартная библиотека С ++», которая очень хорошо охватывает все эти вещи.
источник
Я обычно использую это:
Он многократно вызывает,
std::string::find()
чтобы найти другие вхождения искомой строки, покаstd::string::find()
ничего не находит. Посколькуstd::string::find()
возвращает позицию совпадения, у нас нет проблемы аннулирования итераторов.источник
Это звучит как вариант
string.replace(string.find("%s"), string("%s").size(), "Something");
Вы могли бы обернуть это в функцию, но это решение в одну строку звучит приемлемо. Проблема в том, что это изменит только первый случай, вы можете зацикливаться на нем, но это также позволяет вам вставить несколько переменных в эту строку с одним и тем же token (
%s
)источник
str.replace(str.find("%s"), string("%s").size(), "Something");
Если все строки являются std :: string, вы обнаружите странные проблемы с обрезкой символов при использовании,
sizeof()
потому что она предназначена для строк C, а не строк C ++. Исправление заключается в использовании.size()
метода классаstd::string
.Это заменяет встроенный sHaystack - нет необходимости выполнять задание =.
Пример использования:
источник
источник
Если вы хотите сделать это быстро, вы можете использовать два подхода сканирования. Псевдокод:
Я не уверен, может ли это быть оптимизировано для действующего алгоритма.
И пример кода C ++ 11, но я ищу только один символ.
источник
источник
Моя собственная реализация, учитывая, что размер строки нужно изменить только один раз, тогда может произойти замена.
Использование может быть, например, так:
источник
Я только сейчас изучаю C ++, но редактируя часть ранее опубликованного кода, я бы, вероятно, использовал что-то вроде этого. Это дает вам возможность заменить 1 или несколько экземпляров, а также позволяет указать начальную точку.
источник
Это может быть даже лучше использовать
источник