繁体   English   中英

如何在c ++字符串中搜索非ASCII字符?

[英]How to search a non-ASCII character in a c++ string?

string s="x1→(y1⊕y2)∧z3";

for(auto i=s.begin(); i!=s.end();i++){
    if(*i=='→'){
       ...
    }
} 

字符比较肯定是错误的,这是正确的方法吗? 我正在使用vs2013。

首先,您需要对程序如何处理Unicode有一些基本的了解。 否则,你应该阅读,我非常喜欢这篇关于Joel on Software的帖子

你实际上有两个问题:

问题#1:将字符串输入程序

你的第一个问题就是如何让你的实际的字符串, string s 根据源代码文件的编码,MSVC可能会破坏该字符串中的任何非ASCII字符。

  • 将您的C ++文件保存为UTF-16(Windows令人困惑地称之为Unicode ),并使用whcar_twstring (有效地将表达式编码为UTF-16)。 使用BOM保存为UTF-8也可以。 任何其他编码和您的L"..."字符文字将包含错误的字符。

    请注意,其他平台可能将wchar_t定义为4个字节而不是2个。因此,对U + FFFF以上字符的处理将是不可移植的。

  • 在所有其他情况下,您不能只在源文件中写入这些字符。 最便携的方法是将字符串文字编码为UTF-8,对所有非A​​SCII字符使用\\x转义码。 像这样: "x1\\xe2\\x86\\x92a\\xe2\\x8a\\x95" "b)"而不是"x1→(a⊕b)"

    是的,这就像它变得难以理解和繁琐一样。 根本问题是MSVC并不真正支持使用UTF-8。 您可以在此处查看此问题以获取概述: 如何在Visual C ++ 2008中创建UTF-8字符串文字

    但是,还要考虑这些字符串实际显示在源代码中的频率。

问题#2:找到角色

(如果你使用的是UTF-16,你可以找到L'→'字符,因为那个字符可以表示为一个whcar_t 。对于U + FFFF以上的字符,你将不得不使用下面的宽泛版本的变通方法。 )

定义表示箭头字符的char是不可能的。 但是你可以用一个字符串: "\\xe2\\x86\\x92" (这是一个包含3个箭头字符的字符串,以及\\0终结符。

您现在可以在表达式中搜索此字符串:

s.find("\xe2\x86\x92");

UTF-8编码方案保证始终找到正确的字符,但请记住这是一个以字节为单位的偏移量。

我的评论太大了,所以我将其作为答案提交。

问题是每个人都在关注Unicode可能使用的不同编码问题(UTF-8,UTF-16,UCS2等)。 但是你的问题才刚刚开始。

还有一个复合字符的问题,这将真正搞乱你想要进行的任何搜索。

假设您正在寻找一个字符'é',您会在Unicode中找到它作为U + 00E9并进行搜索,但不能保证这是表示此字符的唯一方法。 该文件还可能包含U + 0065 U + 0301组合。 这实际上是完全相同的角色。

是的,不仅仅是“看起来相同的角色”,而且它完全相同,所以任何软件甚至一些编程库都可以在不告诉你的情况下自由地从一个转换到另一个。

因此,如果您希望进行搜索,这是强大的,您需要的东西不仅代表Unicode的不同编码,而且Unicode字符本身在Composite和现成字符之间具有相等性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM