我们有数据,其中键是可以包含引号的字符串。问题是Visual Basic不尊重普通双引号和斜引号之间的区别。例如。声明:
MessageBox.Show("""1""" = "””1””")
返回True。请注意,我们从python程序生成非常大的脚本文件,并在VB脚本环境中运行它们。我们不是从文件中读取数据。我怎样才能让VB尊重两种报价之间的差异?
答案 0 :(得分:6)
您正在使用VB.Net语言规范,该规范在代码语句中使用时将三个不同的双引号字符视为相同的字符。
字符串文字是零个或多个Unicode字符的序列 以ASCII双引号字符开头和结尾,Unicode 左双引号字符,或Unicode右双引号 字符。在一个字符串中,一个由两个双引号字符组成的序列 是表示字符串中双引号的转义序列。
StringLiteral
: DoubleQuoteCharacter StringCharacter* DoubleQuoteCharacter
;
DoubleQuoteCharacter
: '"'
| '<unicode left double-quote 0x201c>'
| '<unicode right double-quote 0x201D>'
;
StringCharacter
: '<Any character except DoubleQuoteCharacter>'
| DoubleQuoteCharacter DoubleQuoteCharacter
;
在上面引用的规范中,使用&#34; ASCII双引号字符&#34;表示英寸字符或Chrw(34)。
在VS2015之前,您甚至无法将"""1""" = "””1””"
粘贴到代码编辑器中,而不会自动转换为"""1""" = """1"""
。
如果需要构造包含Unicode双引号的代码语句,则需要使用各自的字符表示来构造它们。
Const ucDoubleLeftQuote As Char = ChrW(&H201C) ' "“"c
Const ucDoubleRightQuote As Char = ChrW(&H201D) ' "”"c
Const asciiDoubleQuote As Char = ChrW(34) ' """"c
Dim asciiQuoted As String = """1"""
Dim asciiQuotedv2 As String = asciiDoubleQuote & "1" & asciiDoubleQuote
Dim unicodeQuoted As String = ucDoubleLeftQuote & "1" & ucDoubleLeftQuote
MessageBox.Show((asciiQuoted = asciiQuotedv2).ToString()) ' yields true
MessageBox.Show((asciiQuoted = unicodeQuoted).ToString()) ' yields false
编辑:要演示VB编译器替换字符串文字中任何Unicode双引号的ASCII双引号,请考虑以下代码。
Module Module1
Sub Main()
T1("““ 1 ””") ' unicode quotation marks left and right
T2(""" 1 """) ' ascii quotation mark
End Sub
Sub T1(s As String) ' dummy method to highlight unicode quotation mark
End Sub
Sub T2(s As String) ' dummy method to highlight asci quotation mark
End Sub
End Module
在ILDASM中查看时,此代码将产生以下IL。
.method public static void Main() cil managed
{
.entrypoint
.custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 )
// Code size 24 (0x18)
.maxstack 8
IL_0000: nop
IL_0001: ldstr "\" 1 \""
IL_0006: call void ConsoleApp1.Module1::T1(string)
IL_000b: nop
IL_000c: ldstr "\" 1 \""
IL_0011: call void ConsoleApp1.Module1::T2(string)
IL_0016: nop
IL_0017: ret
} // end of method Module1::Main
IL_0001: ldstr "\" 1 \""
对应于调用语句的字符串加载:T1("““ 1 ””")
。
你可以看到,这与IL_000c: ldstr "\" 1 \""
相同,对应于加载调用语句的字符串:T2(""" 1 """)
。
答案 1 :(得分:0)
由于String本质上是一个Char数组,因此可以比较两个数组是否相同。看一下这个例子:
Option Strict On
Imports System
Imports System.Linq
Public Module Module1
Public Sub Main()
Dim regular_quotes As String = """1"""
Dim slanted_quotes As String = "””1””"
'Using = operator
Console.WriteLine(regular_quotes = slanted_quotes) 'True
'Using equals method
Console.WriteLine(regular_quotes.Equals(slanted_quotes)) 'True
'Using LINQ comparison
Console.WriteLine(CompareCharArray(regular_quotes, slanted_quotes)) 'False
End Sub
Private Function CompareCharArray(ByVal value1 As String, ByVal value2 As String) As Boolean
'Return a False value if the Lengths don't match
If value1.Length <> value2.Length Then
Return False
End If
'Return a False value if the Char at the current index doesn't match
For index As Integer = 0 To value1.Length - 1
If Not value1(index).Equals(value2(index)) Then
Return False
End If
Next
'Return a True value if everything is squared up
Return True
End Function
End Module
小提琴:Live Demo
更新 - 显然当Visual Basic .NET呈现String时,引号(ascii代码137
&amp; 138
)将替换为普通引号(ascii code { {1}});因此,即使遍历两个数组并比较给定索引处的Char也没有帮助。布鲁赫,我不知道还能做些什么。