[.NET] мультизамена.
А как-нибудь прям сразу, за один проход нельзя?КМП на Боре
Если есть строка abcd и правила ab -> lala; abc -> lala, результатом Replace будет lalad или lalacd?
если уж совсем лениво - то можно к результирующим строками приписать какой-нить символ/строку которого точно нигде нет, а потом его/её вычистить.
А если такого символа нет? В Unicode всего-то 65k символов. Ну т.е. конечно такое решение покатит для ситуации завтра война, но оно слишком сильно напоминает тупое решение с null-terminated strings
В таком случае - самый длинный, наверное.
требуется оптимальное по скорости, по памяти или по числу нажатых кнопок для написания?
Самый длинный результат (lalacd) или применяется самое длинное правило (abc -> lala, т.е. lalad)?
Правильное решение должно работать на любой строке. Бывают ситуации, когда устраивают и неправильные решения, но, если есть время, всегда лучше уберечь себя от возможной головной боли от того, что у заказчика программа как-то странно валится на валидных данных
можно, достаточно написать простенький автомат
Дополнительно надеемся, что среди замен нету "0" -> "1", которая наверняка убъёт любой гуид.
Самое правильное, конечно, это сгруппировать все замены ("a1"->"b1", "a2"->"b2" ...) в "(a1)|(a2)|...", дальше сказать Match, дальше пройтись по всем матчам, выяснить, какая именно подскобка сработала в каждом случае и построить новую строчку. Так я и сделаю, пожалуй.
Но!
Если б где-нибудь найти движок типа регесов, но с возможностью более тонкого контроля над работой построенного НКА, можно было бы такие вещи делать жутко быстро.
Самая длинная левая часть, очевидно.
Вот-вот! А писать "простенький автомат" с нуля что-то не хочется.
В Unicode всего-то 65k символов.их там может быть больше,
и для подобных целей там оставлены несколько позиций.
так что нужно только посмотреть конкретные значения.
ИМХО это лучший и наибыстрейший вариант.
так что-то он совсем простой - фактически на два состояния:
ничего не обрабатываем
уже обрабатываем такую-то последовательность символов
хм. Надо будет почитать про это. Только меня сомнения берут, что в .net можно сделать строку с такими "читерскими" символами
имхо, быстрее будет решить задачу честно.
вход: bacd
правила: aсd -> x; ba -> y
что хотим получить?
bx или ycd?
а что .net только базовый юникод держит?
все символы ровно два байта?
upd. Да, на символ - два байта. Если хочется использовать боле 65k символов, используется суррогатная пара, где первый байт из диапазона [08000, 0fff]. Так же делается в UTF-16. Но это, разумеется, геморрой и поддержка этой возможности фактически на пользователе
x_1 => y_1
x_2 => y_2
...
x_n => y_n
Поиск по регулярному выражению вида
x_1|x_2|...|x_n
и замена по хэш-таблице.
Оставить комментарий
bleyman
Есть некоторый набор замен вида "подстрока1" -> "подстрока2", причём заранее неизвестный. Хочется применить их тексту не по очереди, а одновременно (то есть чтобы результат первой замены не влиял на вторую (например, "a"->"b", "b" -> "c" должно преобразовать "abc" -> "bcc" (а не "ccc", как если их применить по очереди.Один вариант - разбивать замены на "подстрока1" -> guid, guid -> "подстрока2", и надеятся, что такого гуида в тексте/заменах не попадётся (можно даже проверить).
Или можно вместо Regex.Replace получить все позиции нужных слов, запомнить их, а потом заменить ручками.
А как-нибудь прям сразу, за один проход нельзя?