带有特殊表情符号的字符串的子字符串,字符串.IndexOf返回-1

本文关键字:字符串 IndexOf 返回 符号 | 更新日期: 2023-09-27 18:08:22

我有一个带有特殊表情符号的字符串:

string test = "<textarea style='display:none;'>˃̣̣̥᷄⌓˂̣̣̥᷅  abcde";

我想得到这个字符串的子字符串,如下所示:

string sub = test.Substring(test.IndexOf(">"));

(因为字符串"test"的第一个">"意味着HTML代码的结束)

(我想要的结果是˃̣̣̥᷄⌓˂̣̣̥᷅ abcde)

然而,Substring方法返回一个错误("StartIndex不能小于0"),这意味着字符串'test '中没有'>。

所以我测试了如下内容:
test.Contains(">");

返回'True '

这是我的问题:Contains方法说字符串'test'包含'>'在它,但Substring方法不能正常工作…

如何从字符串'test'中获得正确的子字符串?

带有特殊表情符号的字符串的子字符串,字符串.IndexOf返回-1

正如其他人已经说过的,IndexOf(">")执行文化敏感搜索。这意味着你必须记住,有些字符基本上是不同unicode字符的组合。

让我们看看字符串的这一部分:;'>˃̣̣̥᷄⌓˂̣̣̥᷅

包含以下unicode字符:

SEMICOLON (U+003B) 
APOSTROPHE (U+0027) 
GREATER-THAN SIGN (U+003E) 
MODIFIER LETTER RIGHT ARROWHEAD (U+02C3) 
COMBINING DOT BELOW (U+0323) 
COMBINING DOT BELOW (U+0323) 
COMBINING RING BELOW (U+0325) 
COMBINING MACRON-ACUTE (U+1DC4) 
SEGMENT (U+2313) 
MODIFIER LETTER LEFT ARROWHEAD (U+02C2) 
COMBINING DOT BELOW (U+0323) 
COMBINING DOT BELOW (U+0323) 
COMBINING RING BELOW (U+0325) 
COMBINING GRAVE-MACRON (U+1DC5) 

请注意,虽然它包含一个GREATER-THAN SIGN (U+003E >)字符,但请注意它后面跟着一个MODIFIER LETTER RIGHT ARROWHEAD (U+02C3 ˃)字符。该字符是一个所谓的间距修饰符,用于改变前一个或后一个字符的含义。

此行为与以下字符(COMBINING DOT BELOW, COMBINING RING BELOW)非常相似,它们是组合变音符,但这些通常放在它们修改的字符的顶部或下方(如图所示):̣̣̥᷄⌓是一个SEGMENT,由两个DOT BELOW,一个RING BELOW和一个MACRON_ACUTE修改而成。

因此,如果您考虑了字符组合(IndexOf(String)),那么您的字符串不包含字符串>(单个大于号)。

要检查单个(非组合)字符,您可以使用IndexOf('>')(使用char而不是string):

此方法执行顺序(不区分区域性)搜索,其中只有当一个字符的Unicode标量值相同时,才认为它们与另一个字符相等。

test.IndexOf(">", StringComparison.Ordinal) .


也就是说,如果你想解析HTML,最好使用HTML解析器,如HTML Agility Pack:

string html = "<textarea style='display:none;'>˃̣̣̥᷄⌓˂̣̣̥᷅  abcde</textarea>";
HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
htmlDoc.LoadHtml(html);
var value = htmlDoc.DocumentNode.SelectSingleNode("//textarea").InnerText;

value现在包含˃̣̣̥᷄⌓˂̣̣̥᷅ abcde

使用单引号。

string sub = test.Substring(test.IndexOf('>'));

如果你想使用"strings"而不是" c " char,你需要指定一个stringComparison Type。

string test = "<textarea style='display:none;'>˃̣̣̥᷄⌓˂̣̣̥᷅  abcde"; 
string sub = test.Substring(test.IndexOf(">", StringComparison.Ordinal));
Console.WriteLine(test.IndexOf(">", StringComparison.Ordinal));
Console.WriteLine(sub);

string.IndexOf(string s)的默认行为是做StringComparison.CurrentCulture文化敏感的比较。

字符串。IndexOf方法(字符串)(系统)@ MSDN