2008-12-02 16 views
28

Mi post de abajo preguntó cuáles eran las comillas tipográficas y por qué mi aplicación no funcionaría con ellos, mi pregunta ahora es ¿cómo puedo reemplazar cuando mi programa viene a través de ellos, ¿cómo puedo hacer esto en C#? ¿Son personajes especiales?C# ¿Cómo reemplazar las citas inteligentes de Microsoft con comillas simples?

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

Gracias

+2

Las comillas de los tipógrafos no son menos reales que las comillas simples. –

Respuesta

3

acuerdo con la aplicación Mapa de caracteres que viene con Windows, los valores Unicode para las cotizaciones rizados son 0x201c y 0x201d. Reemplace esos valores con la cita recta 0x0022, y debería estar listo para continuar.

String.Replace(0x201c, '"'); 
String.Replace(0x201d, '"'); 
5

Tenga en cuenta que lo que tiene es inherentemente un archivo CSV corrupto. Cambiar indiscriminadamente las citas de todos los tipógrafos con comillas simples no necesariamente arreglará su archivo. Por lo que usted sabe, se suponía que algunas de las citas del tipógrafo estaban allí, como parte del valor de un campo. Sustituirlos por comillas simples puede que tampoco te dejen con un archivo CSV válido.

No creo que hay una manera algorítmica para fijar un archivo que está dañado en la manera que usted describe. Su tiempo podría ser mejor invertido en investigar cómo se obtienen esos archivos inválidos en primer lugar, y luego detenerlo. ¿Alguien está usando Word para editar sus archivos de datos, por ejemplo?

+0

Erm, no creo que esta pregunta tenga nada que ver con los archivos CSV ... :) –

+0

No, pero la pregunta de OP hace. – GalacticCowboy

23

Cuando me encontré con este problema me escribió un método de extensión a la clase String en 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; 
    } 
} 

Esto simplemente reemplaza las "citas inteligentes" tontas con comillas normales.

[EDIT] fijo para apoyar también la sustitución de 'comillas inteligentes'.

+1

Su código funciona con comillas simples, necesita usar \ u201c y \ u201d para comillas dobles. –

+0

Reparado. Gracias hombre. –

3

que tienen en su conjunto una gran gran ... ... programa que hace precisamente esto. Puede arrancar el script y usarlo a su gusto. Se hace todo tipo de reemplazos, y está situado en http://bitbucket.org/nesteruk/typografix

1

probar esto por comillas simples inteligentes si lo anterior no funcionan:

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

probar este, así como para comillas dobles inteligentes:

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

una lista más extensa de caracteres de palabra problemáticas

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', '\"'); 
+3

Tengo curiosidad, ¿alguien ha realizado pruebas de rendimiento que muestren que .IndexOf() es más barato que ejecutar .Replace() en una cadena que no contiene el carácter? –

+0

La operación más económica sería iterar la cadena una sola vez, frente a iterar posiblemente hasta 2 * cantidad de caracteres dirigidos. Por ejemplo: 'foreach (char c en buffer) {/ * si char en la lista a reemplazar, reemplaza * /}'. – Dan

1

También tengo un programa que hace esto, la fuente está en this file de CP-1252 Fixer. También define algunas asignaciones para convertir caracteres dentro de cadenas RTF conservando todo el formato, lo que puede ser útil para algunos.

También es un mapeo completo de todos los caracteres "Cita inteligente" a sus homólogos de baja ASCII, códigos de entidad y las referencias de caracteres.

3

La VB equivalente de lo que escribió @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 
4

Extender sobre la respuesta popular de Nick van Esch, aquí está el código con los nombres de los personajes en los comentarios.

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 
+3

Hola Barbara. Útil para la respuesta, pero sería más adecuado como una edición sugerida de la respuesta existente en lugar de una nueva. – Stijn

+0

@Barbara, Hola, ¿no hay algún método que pueda reemplazar todos los caracteres sin especificar cada carácter manualmente? Si en el futuro, hay otros caracteres aparte de los especificados anteriormente en el código, entonces? –

+0

Es el requisito actual en nuestro caso. Cualquier caracter especial del archivo MS Word puede venir y debe convertirse a caracteres Rectos y mostrarse correctamente. –

0

que trabajó para mí, se puede tratar a continuación el código

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

Gracias!

Cuestiones relacionadas