VB不尊重“和”1“

时间:2018-03-27 21:10:59

标签: vb.net

我们有数据,其中键是可以包含引号的字符串。问题是Visual Basic不尊重普通双引号和斜引号之间的区别。例如。声明:

MessageBox.Show("""1""" = "””1””") 

返回True。请注意,我们从python程序生成非常大的脚本文件,并在VB脚本环境中运行它们。我们不是从文件中读取数据。我怎样才能让VB尊重两种报价之间的差异?

2 个答案:

答案 0 :(得分:6)

您正在使用VB.Net语言规范,该规范在代码语句中使用时将三个不同的双引号字符视为相同的字符。

来自String Literals

  

字符串文字是零个或多个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也没有帮助。布鲁赫,我不知道还能做些什么。