2011-04-27 169 views
12

我有一个asp.net c#页面,并试图读取具有以下字符的文件'并将其转换为'。 (从倾斜的撇号到撇号)。阅读一个Unicode字符的文件

FileInfo fileinfo = new FileInfo(FileLocation); 
string content = File.ReadAllText(fileinfo.FullName); 

//strip out bad characters 
content = content.Replace("’", "'"); 

这不工作,它改变了倾斜撇号到?分数。

+0

有什么问题? – BrokenGlass 2011-04-27 00:49:01

+0

你说它把倾斜的那个改成了“?”。这意味着您的替换函数的第一个参数是正确的,但第二个参数是错误的。它可能是一个Unicode字符,*看起来像单引号,但实际上不是单引号。在没有Unicode字体的显示中,或者在打印到屏幕时,无法识别的Unicode字符显示为“?”。 – 2011-04-27 02:08:25

+0

检查第二个参数是否是正确的字符。您可能无意中打开了一个亚洲IME或其他东西,然后键入一个亚洲引号字符(即Unicode),该字符在屏幕上看起来就像一个简单的引号。有时很难区分差异。 – 2011-04-27 02:09:33

回答

1
// This should replace smart single quotes with a straight single quote 

Regex.Replace(content, @"(\u2018|\u2019)", "'"); 

//However the better approach seems to be to read the page with the proper encoding and leave the quotes alone 
var sreader= new StreamReader(fileInfo.Create(), Encoding.GetEncoding(1252)); 
0

如果您使用字符串(大写)而不是字符串,它应该能够处理任何你扔在它的Unicode。先试试看看是否有效。

+3

一个是另一个的别名,这不会改变任何东西。 – BrokenGlass 2011-04-27 01:59:11

+0

你是对的!那么我会假设引号是不是2018/9,也许依赖于语言环境。将其转换为int或short来获取Unicode值,并将\ u + thatNumber替换为之前发布的内容。 – kappasims 2011-04-27 02:06:30

15

我怀疑问题不在于替换,而在于读取文件本身。当我尝试这种方式(使用Word和复制粘贴)时,我得到了和你一样的结果,但是检查content表明.Net框架认为该字符是Unicode字符65533,即“WTF?”。字符之前字符串替换。您可以通过在Visual Studio调试器,它应该显示的字符代码检查相关字符检查这个自己:

content[0]; // 65533 '�' 

之所以更换不工作很简单 - content不含字符串你给它:

content.IndexOf("’"); // -1 

至于为什么文件读取工作不正常 - 读取文件时,你可能使用了错误的编码。 (如果没有指定编码,那么.Net框架会尝试为你确定正确的编码,但是没有100%可靠的方法来做到这一点,所以经常会出错)。你需要精确编码依赖于文件本身,但在我的情况下,编码使用是Extended ASCII,所以读我只需要指定正确的编码文件:

string content = File.ReadAllText(fileinfo.FullName, Encoding.GetEncoding("iso-8859-1")); 

(见this question)。

您还需要确保在替换字符串中指定了正确的字符 - 在代码中使用“奇数”字符时,可能会发现通过其字符代码指定字符更可靠,而不是字符串文字(这可能会导致问题,如果源文件的变化的编码),例如下列为我工作:

content = content.Replace("\u0092", "'"); 
+2

而不是'(char)146',''\ u0092''可能更具可读性,因为它匹配字符代码图表。 – 2011-04-27 04:16:20

+0

@Jeffrey谢谢 - 我已经更新了我的答案。 – Justin 2011-04-27 04:21:42

+0

=='(char)146'的原因是因为'\ u'表示法使用十六进制,'0x92 == 146' – Justin 2011-04-27 04:27:28

1

我的选择是该文件中Windows-1252编码。这与差不多与ISO 8859-1相同。区别在于Windows-1252使用“可显示的字符,而不是控制字符在0x80到0x9F范围内”。 (这是倾斜的撇号所在的位置,即0x92)

//Specify Windows-1252 here 
string content = File.ReadAllText(fileinfo.FullName, Encoding.GetEncoding(1252)); 
//Your replace code will then work as is 
content = content.Replace("’", "'"); 
+0

Encoding.GetEncoding(“Windows-1252”) – Daniel 2016-08-25 07:01:44