C ++ / Boost string replace: как заменить '&' на '&' только тогда, когда & заканчивается на; - PullRequest
1 голос
/ 18 марта 2011

Я заменяю xml, и мне нужно заменить символ & на & только тогда, когда символ & заканчивается точкой с запятой.

Конечно, я могусделайте это с replace_if, replace_all, или, может быть, с поддержкой регулярных выражений в boost, но я чувствую себя сегодня глупым ... не могу найти то, что мне нужно.

Ответы [ 5 ]

1 голос
/ 18 марта 2011

Я полагаю, что выражение sed s/&([^ ]*);/&\1;/g сделает замену, которую вы ищете. Я не знаком с заменой строк в boost, но в документации сказано, что она поддерживает регулярные выражения в стиле sed.

Edit: после тестирования его в sed, выражение, похоже, нуждается в еще большем экранировании. s/\&\([^ ]*\);/\&\1;/g работает для моих тестовых случаев.

Редактировать 2: Немного улучшено выражение и разбивка:

s#&\([^[:space:]]*\);#\&\1;#g

Шаблон ввода:

& начинается с буквального символа &

\([^[:space:]]*\) сопоставление и захват любого количества непробельных символов

; оканчивается литералом;

Схема вывода:

\& литеральный символ & (необходимо экранировать в шаблоне вывода, поскольку & обычно представляет всю совпадающую строку там)

amp; литерал

\1 распечатать захваченную строку непробельных символов

; буквальный;

0 голосов
/ 19 марта 2011

Можете ли вы использовать отрицательное использование упреждения?

/\&(?![A-Za-z]+\;)/

Соответствует любому символу &, за которым не следует нормальное слово плюс точка с запятой.

Однако не всеСистемы поддерживают прогнозирование.Если у вас нет, то вам придется сначала заменить все &, а затем преобразовать неправильные обратно.Без негативных осмотров регулярные выражения не годятся вообще, если не соответствует чему-либо.

0 голосов
/ 18 марта 2011
  1. Заменить & на & amp;
  2. Заменить & amp; с & amp;
  3. Прибыль

(пробелы вставлены для предотвращения их замены самим stackoverflow!)

0 голосов
/ 18 марта 2011

Это не должно быть так сложно.Используйте std :: find для перехода к следующему &, а затем просмотрите вперед, используя find_if, find_first_of или boost :: regex, чтобы найти либо ';', либо что-то, что заставит вас прекратить поиск.Должно работать что-то вроде следующего (непроверенного):

struct EndMatch
{
    bool operator()( char ch ) const
    {
        return isspace( static_cast<unsigned char>( ch ) ) || ch == ';' ;
    }
};

std::string
replaceAmp(std::string const& original)
{
    typedef std::string::const_iterator TextIter;
    std::string results;
    TextIter current = original.begin();
    TextIter end = original.end();
    TextIter next = std::find( current, end, '&' );
    while (next != end) {
        results.append( current, next );
        current = next;
        next = std::find_if( current, end, EndMatch() );
        if ( next == end || *next != ';' ) {
            results.append( "&amp;" );
        } else {
            results.append( '&' );
        }
        ++ current;  // Skip '&', processed above
        next = std::find( current, end, '&' );
    }
    results.append( current, next );
    return results;
}
0 голосов
/ 18 марта 2011

Вы можете попробовать использовать следующее регулярное выражение с отрицательным прогнозом:

(&)(?!\S*;)

Это соответствует &, только если за ним не следует непробельный символ (символы), за которым следует ;.

Сценарий Perl, использующий приведенное выше регулярное выражение

Я не уверен, допускает ли регулярное выражение boost отрицательный прогноз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...