C # Как заменить смарт-кавычки Microsoft на прямые кавычки? - PullRequest
29 голосов
/ 02 декабря 2008

В моем посте ниже спрашивалось, что такое фигурные кавычки и почему мое приложение не работает с ними, теперь мой вопрос: как я могу заменить их, когда моя программа сталкивается с ними, как я могу сделать это в C #? Это специальные символы?

фигурные кавычки-противы-квадратных кавычек-что-дают

Спасибо

Ответы [ 11 ]

47 голосов
/ 05 февраля 2010

Более обширный список проблемных символов слова

if (buffer.IndexOf('\u2013') > -1) buffer = buffer.Replace('\u2013', '-');
if (buffer.IndexOf('\u2014') > -1) buffer = buffer.Replace('\u2014', '-');
if (buffer.IndexOf('\u2015') > -1) buffer = buffer.Replace('\u2015', '-');
if (buffer.IndexOf('\u2017') > -1) buffer = buffer.Replace('\u2017', '_');
if (buffer.IndexOf('\u2018') > -1) buffer = buffer.Replace('\u2018', '\'');
if (buffer.IndexOf('\u2019') > -1) buffer = buffer.Replace('\u2019', '\'');
if (buffer.IndexOf('\u201a') > -1) buffer = buffer.Replace('\u201a', ',');
if (buffer.IndexOf('\u201b') > -1) buffer = buffer.Replace('\u201b', '\'');
if (buffer.IndexOf('\u201c') > -1) buffer = buffer.Replace('\u201c', '\"');
if (buffer.IndexOf('\u201d') > -1) buffer = buffer.Replace('\u201d', '\"');
if (buffer.IndexOf('\u201e') > -1) buffer = buffer.Replace('\u201e', '\"');
if (buffer.IndexOf('\u2026') > -1) buffer = buffer.Replace("\u2026", "...");
if (buffer.IndexOf('\u2032') > -1) buffer = buffer.Replace('\u2032', '\'');
if (buffer.IndexOf('\u2033') > -1) buffer = buffer.Replace('\u2033', '\"');
24 голосов
/ 02 декабря 2008

Когда я столкнулся с этой проблемой, я написал метод расширения для класса String в C #.

public static class StringExtensions
{
    public static string StripIncompatableQuotes(this string s)
    {
        if (!string.IsNullOrEmpty(s))
            return s.Replace('\u2018', '\'').Replace('\u2019', '\'').Replace('\u201c', '\"').Replace('\u201d', '\"');
        else
            return s;
    }
}

Это просто заменяет глупые «умные цитаты» обычными кавычками.

[EDIT] Исправлено, чтобы также поддерживать замену «двойных умных кавычек».

6 голосов
/ 15 мая 2015

Чтобы расширить популярный ответ Ника ван Эша, вот код с именами символов в комментариях.

if (buffer.IndexOf('\u2013') > -1) buffer = buffer.Replace('\u2013', '-'); // en dash
if (buffer.IndexOf('\u2014') > -1) buffer = buffer.Replace('\u2014', '-'); // em dash
if (buffer.IndexOf('\u2015') > -1) buffer = buffer.Replace('\u2015', '-'); // horizontal bar
if (buffer.IndexOf('\u2017') > -1) buffer = buffer.Replace('\u2017', '_'); // double low line
if (buffer.IndexOf('\u2018') > -1) buffer = buffer.Replace('\u2018', '\''); // left single quotation mark
if (buffer.IndexOf('\u2019') > -1) buffer = buffer.Replace('\u2019', '\''); // right single quotation mark
if (buffer.IndexOf('\u201a') > -1) buffer = buffer.Replace('\u201a', ','); // single low-9 quotation mark
if (buffer.IndexOf('\u201b') > -1) buffer = buffer.Replace('\u201b', '\''); // single high-reversed-9 quotation mark
if (buffer.IndexOf('\u201c') > -1) buffer = buffer.Replace('\u201c', '\"'); // left double quotation mark
if (buffer.IndexOf('\u201d') > -1) buffer = buffer.Replace('\u201d', '\"'); // right double quotation mark
if (buffer.IndexOf('\u201e') > -1) buffer = buffer.Replace('\u201e', '\"'); // double low-9 quotation mark
if (buffer.IndexOf('\u2026') > -1) buffer = buffer.Replace("\u2026", "..."); // horizontal ellipsis
if (buffer.IndexOf('\u2032') > -1) buffer = buffer.Replace('\u2032', '\''); // prime
if (buffer.IndexOf('\u2033') > -1) buffer = buffer.Replace('\u2033', '\"'); // double prime
5 голосов
/ 02 декабря 2008

Обратите внимание, что у вас по сути поврежденный файл CSV. Беспорядочная замена всех цитат типографа прямыми не обязательно исправит ваш файл. Насколько вы знаете, некоторые цитаты типографа должны были присутствовать как часть значения поля. Замена их прямыми кавычками может и не дать вам действительный файл CSV.

Я не думаю, что есть алгоритмический способ исправить поврежденный файл, как вы описываете. Ваше время может быть лучше потрачено на то, чтобы выяснить, откуда у вас появились такие недействительные файлы, а затем положить этому конец. Кто-то использует Word для редактирования ваших файлов данных, например?

3 голосов
/ 19 апреля 2013

VB эквивалент того, что написал @Matthew:

Public Module StringExtensions

    <Extension()>
    Public Function StripIncompatableQuotes(BadString As String) As String
        If Not String.IsNullOrEmpty(BadString) Then
            Return BadString.Replace(ChrW(&H2018), "'").Replace(ChrW(&H2019), "'").Replace(ChrW(&H201C), """").Replace(ChrW(&H201D), """")
        Else
            Return BadString
        End If
    End Function
End Module
3 голосов
/ 03 декабря 2008

У меня есть целая большая ... программа ... которая делает именно это. Вы можете вырвать сценарий и использовать его на свое усмотрение. Это делает все виды замен, и расположено в http://bitbucket.org/nesteruk/typografix

3 голосов
/ 02 декабря 2008

В соответствии с приложением Character Map, которое поставляется с Windows, значения Unicode для фигурных кавычек - 0x201c и 0x201d. Замените эти значения на прямую кавычку 0x0022, и все будет хорошо.

String.Replace(0x201c, '"');
String.Replace(0x201d, '"');
1 голос
/ 15 апреля 2011

У меня также есть программа, которая делает это, источник находится в этом файле из CP-1252 Fixer . Кроме того, он определяет некоторые отображения для преобразования символов в строках RTF при сохранении всего форматирования, что может быть полезно для некоторых.

Это также полное сопоставление всех"умных кавычек" символов с их низкоуровневыми аналогами, кодами сущностей и ссылками на символы.

1 голос
/ 05 февраля 2010

Попробуйте это для умных одинарных кавычек, если вышеприведенное не работает:

string.Replace("\342\200\230", "'")
string.Replace("\342\200\231", "'")

Попробуйте это и для умных двойных кавычек:

string.Replace("\342\200\234", '"')
string.Replace("\342\200\235", '"')
0 голосов
/ 06 июля 2018

Используя ответы Ника и Барбары, вот пример кода со статистикой производительности для 1 000 000 циклов на моей машине:

input = "shmB6BhLe0gdGU8OxYykZ21vuxLjBo5I1ZTJjxWfyRTTlqQlgz0yUtPu8iNCCcsx78EPsObiPkCpRT8nqRtvM3Bku1f9nStmigaw";
input.Replace('\u2013', '-'); // en dash
input.Replace('\u2014', '-'); // em dash
input.Replace('\u2015', '-'); // horizontal bar
input.Replace('\u2017', '_'); // double low line
input.Replace('\u2018', '\''); // left single quotation mark
input.Replace('\u2019', '\''); // right single quotation mark
input.Replace('\u201a', ','); // single low-9 quotation mark
input.Replace('\u201b', '\''); // single high-reversed-9 quotation mark
input.Replace('\u201c', '\"'); // left double quotation mark
input.Replace('\u201d', '\"'); // right double quotation mark
input.Replace('\u201e', '\"'); // double low-9 quotation mark
input.Replace("\u2026", "..."); // horizontal ellipsis
input.Replace('\u2032', '\''); // prime
input.Replace('\u2033', '\"'); // double prime

Время: 958,1011 миллисекунд

input = "shmB6BhLe0gdGU8OxYykZ21vuxLjBo5I1ZTJjxWfyRTTlqQlgz0yUtPu8iNCCcsx78EPsObiPkCpRT8nqRtvM3Bku1f9nStmigaw";
var inputArray = input.ToCharArray();
for (int i = 0; i < inputArray.Length; i++)
{
    switch (inputArray[i])
    {
        case '\u2013':
            inputArray[i] = '-';
            break;
        // en dash
        case '\u2014':
            inputArray[i] = '-';
            break;
        // em dash
        case '\u2015':
            inputArray[i] = '-';
            break;
        // horizontal bar
        case '\u2017':
            inputArray[i] = '_';
            break;
        // double low line
        case '\u2018':
            inputArray[i] = '\'';
            break;
        // left single quotation mark
        case '\u2019':
            inputArray[i] = '\'';
            break;
        // right single quotation mark
        case '\u201a':
            inputArray[i] = ',';
            break;
        // single low-9 quotation mark
        case '\u201b':
            inputArray[i] = '\'';
            break;
        // single high-reversed-9 quotation mark
        case '\u201c':
            inputArray[i] = '\"';
            break;
        // left double quotation mark
        case '\u201d':
            inputArray[i] = '\"';
            break;
        // right double quotation mark
        case '\u201e':
            inputArray[i] = '\"';
            break;
        // double low-9 quotation mark
        case '\u2026':
            inputArray[i] = '.';
            break;
        // horizontal ellipsis
        case '\u2032':
            inputArray[i] = '\'';
            break;
        // prime
        case '\u2033':
            inputArray[i] = '\"';
            break;
        // double prime
    }
}
input = new string(inputArray);

Время: 362,0858 миллисекунд

...