web-dev-qa-db-ja.com

C#MicrosoftのSmart Quotesをまっすぐな引用符に置き換える方法は?

以下の私の投稿では、中引用符とは何か、なぜアプリがそれらで機能しないのかを尋ねました。私の質問は、プログラムがそれらに遭遇したときにそれらをどのように置き換えることができるか、C#でこれをどのように行うことができるかです。彼らは特殊文字ですか?

curly-quotation-marks-vs-square-quotation-marks-what-gives

ありがとう

29
Jason P

問題のある単語文字のより広範なリスト

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', '\"');
49
Nick van Esch

この問題が発生したとき、C#でStringクラスの拡張メソッドを作成しました。

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;
    }
}

これは、ばかげた「スマートクォート」を通常のクォートに置き換えるだけです。

[編集]「二重引用符」の置換もサポートするように修正されました。

24
Matthew Ruston

Nick van Eschの一般的な回答を拡張するために、コメントに登場人物の名前が記載されたコードを次に示します。

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
7

あなたが持っているものは本質的に破損したCSVファイルであることに注意してください。すべてのタイポグラファーの引用符を無差別にまっすぐな引用符に置き換えても、必ずしもファイルが修正されるとは限りません。ご存知のとおり、タイポグラファーの引用の一部は、フィールドの値の一部としてそこにあるはずでした。それらを一重引用符で置き換えると、有効なCSVファイルが残らない場合もあります。

あなたが説明した方法で破損しているファイルを修正するアルゴリズム的な方法はないと思います。そもそもこのような無効なファイルがどのようにして発生するのかを調査し、それを阻止することに時間を費やしたほうがよいかもしれません。たとえば、誰かがWordを使用してデータファイルを編集していますか?

5
Rob Kennedy

Windowsに付属の文字コード表アプリケーションによると、中引用符のUnicode値は0x201cと0x201dです。これらの値を一重引用符0x0022に置き換えれば、問題はありません。

String.Replace(0x201c, '"');
String.Replace(0x201d, '"');
3
Mark Ransom

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
cjbarth

私は非常に大きな...プログラムを持っています...それはまさにこれを行います。スクリプトを取り除いて、自由に使用できます。あらゆる種類の置換を行い、 http://bitbucket.org/nesteruk/typografix にあります。

3
Dmitri Nesteruk

私もこれを行うプログラムを持っています、ソースは このファイルCP-1252フィクサー にあります。さらに、すべてのフォーマットを保持しながら、RTF文字列内の文字を変換するためのいくつかのマッピングを定義します。これは、一部の人にとって役立つ場合があります。

また、allの「スマートクォート」文字を、対応する低ASCII文字、エンティティコード、および文字参照に完全にマッピングします。

1
pospi

上記が機能しない場合は、スマートな一重引用符でこれを試してください。

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

スマートな二重引用符についてもこれを試してください。

string.Replace("\342\200\234", '"')
string.Replace("\342\200\235", '"')
1
user266768

NickとBarbaraの回答を使用して、次のコードは、私のマシンでの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ミリ秒

0
Taylor Wallgren

それは私のために働いた、あなたは以下のコードを試すことができます

string replacedstring = ("your string with smart quotes").Replace('\u201d', '\'');

ありがとう!

0
Asif Ghanchi