Проблема с поиском и заменой апострофа (') в Word Docx с использованием OpenXML и Regex - PullRequest
7 голосов
/ 29 октября 2019

Word, похоже, использует символ апострофа, отличный от Visual Studio, и это вызывает проблемы с использованием Regex.

Я пытаюсь редактировать некоторые документы Word в C #, используя OpenXML. Я в основном заменяю [[COMPANY]] названием компании. Это работало довольно гладко, пока я не дошел до своего углового примера компаний с именами, заканчивающимися на s. Я в конечном итоге с проблемой s, где иногда это создает s.

Пример: Название компании: Симмонс Текст на Док .: Бизнес [[COMPANY]] - автомобили. Результат: бизнес Симмонса - автомобили.

Это неправильный английский.

Я мог бы просто использовать базовый поиск и замену, как я сделал для [[COMPANY]], но он не работает.

            Regex apostropheReplace = new Regex("s\\'s");
            docText = apostropheReplace.Replace(docText, "s\'"); 

Это не так. Кажется, что Word использует символ и апостроф ('), отличный от стандартного, который создается, когда я использую клавишу на клавиатуре в Visual Studio. Если я напишу поиск и замену с помощью клавиатуры, это не сработает, но если я скопирую и вставлю апостроф из Word, это сработает.

            Regex apostrophyReplace = new Regex("s\\’s");
            docText = apostrophyReplace.Replace(docText, "s\'"); 

Обратите внимание на другой символ в регулярном выражении для второго. Я не понимаю, почему это так, и также хочу знать, является ли правильный способ сделать это. Я пытался "" ", но это не работает. Я просто хочу знать, является ли использование скопированного символа из Word правильным способом сделать это, и есть ли способ сделать это так, чтобы оба символа работали, чтобы у меня не было проблем с документами, которые могут быть созданы с другимпрограмма.

Ответы [ 2 ]

3 голосов
/ 29 октября 2019

Отвечая на вопрос:

Есть ли способ сделать так, чтобы оба персонажа работали?

Если вы хотите, чтобы один Regex мог обрабатывать оба сценарияВозможно, это простое и удобочитаемое решение:

 Regex apostropheReplace = new Regex("s\\['’]s");
 docText = apostropheReplace.Replace(docText, "s\'")

Это дает дополнительное преимущество, заключающееся в том, что другие разработчики понимают, что вы пытаетесь охватить оба случая апострофа. Это преимущество можно получить по другой части вашего вопроса:

Если использование скопированного символа из Word является правильным способом сделать это?

Это зависит от того, что вы имеете в виду"правильно". Если вы имеете в виду «наиболее понятным для других разработчиков», я бы сказал, что да, потому что было бы наименьшее количество запросов, необходимых для точного определения того, что ищет ваш Regex. Если вы имеете в виду «наиболее производительный», это не должно быть проблемой с этим простым поиском Regex (некоторые хорошие советы по производительности Regex можно найти здесь ).

Если вы имеете в виду «наиболее универсальный /надежная одинарная кавычка Regex ", тогда, как указывает @ Leonardo-Seccia, существуют другие кодировки символов, которые могут вызвать проблемы. (Некоторые из распространенных Microsoft Word перечислены здесь здесь .) Такое решение может выглядеть следующим образом:

Regex apostropheReplace =
    new Regex("s\\['\u2018\u2019\u201A\u201b]s");
docText = apostropheReplace.Replace(docText, "s\'")

Но вы, безусловно, можете добавлять другие кодировки символов по мере необходимости. Более полный список кодировок символов можно найти здесь - чтобы добавить их к приведенному выше регулярному выражению, просто измените «U +» на «u» и добавьте его в список после другого символа «\». Например, чтобы добавить «простой» символ (′ или U + 2032) в приведенный выше список, измените строку RegEx с

Regex("s\\['\u2018\u2019\u201A\u201b]s")

на

Regex("s\\['\u2018\u2019\u201A\u201b\u2032]s")

В конечном итоге вы быОпределите, какие кодировки символов являются наиболее «подходящими» для включения в ваше регулярное выражение на основе ваших вариантов использования.

3 голосов
/ 29 октября 2019

Причина в том, что это разные персонажи.

Word фактически изменяет некоторые знаки препинания после того, как вы набираете их, чтобы придать им правильный наклон или улучшить представление.

Я сталкивался с той же самой проблемой раньше и использовал ее как регулярное выражение: [\u2018\u2019\u201A\u201b\u2032']

Поэтому по существу измените ваш код так:

Regex apostropheReplace = new Regex("s\\[\u2018\u2019\u201A\u201b\u2032']s");
docText = apostropheReplace.Replace(docText, "s\'")

Я обнаружил, что это были пять наиболее распространенных типов одинарных кавычек и апострофов.

И вЕсли вы столкнулись с той же проблемой с двойными кавычками, вот что вы можете использовать: [\u201C\u201D\u201E\u201F\u2033\u2036\"]

...