【问题标题】:Sorting String with Numbers using VB Script使用 VB 脚本对带数字的字符串进行排序
【发布时间】:2016-10-23 02:23:10
【问题描述】:

如何使用 VB 脚本对带有数值的字符串进行排序?

以下是表格中每一行的字符串:

  1. “测试 1 通过 dec 2”
  2. “测试 3 失败”
  3. “测试 2 于 6 月 4 日通过”
  4. “已验证”
  5. “测试 10 通过”
  6. “用户接受”

我想在排序后按以下顺序(自然顺序):

  1. “测试 1 通过 dec 2”
  2. “测试 2 于 6 月 4 日通过”
  3. “测试 3 失败”
  4. “测试 10 通过”
  5. “用户接受”
  6. “已验证”

到目前为止我尝试过的方法,

Set oAlist=CreateObject("System.Collections.ArrayList")
oAlist.sort

ArrayList 根据我不喜欢的 ASCII 按以下顺序排序:

  1. “测试 1 通过 dec 2”
  2. “测试 10 通过”
  3. “测试 2 于 6 月 4 日通过”
  4. “测试 3 失败”
  5. “用户接受”
  6. “已验证”

我试过这个链接Sort

我不知道如何在我的情况下使用 AppendFormat

注意:我给定的字符串要么完全是字符串,要么是带有数字的字符串(动态),所以我不知道如何在这里使用 RecordSet 或 AppendFormat,因为我是编程新手。

【问题讨论】:

  • 我对您在这里真正使用的内容感到困惑。 Systems.Collections.ArrayList 是一个 .Net 对象...所以您使用旧的 vbscript 来处理 VB.Net 类型?

标签: sorting vbscript qtp hp-uft


【解决方案1】:

你可以再举一个例子。

Sub Sort
    Set rs = CreateObject("ADODB.Recordset")
    If LCase(Arg(1)) = "n" then
    With rs
        .Fields.Append "SortKey", 4 
        .Fields.Append "Txt", 201, 5000 
        .Open
        Do Until Inp.AtEndOfStream
            Lne = Inp.readline
            SortKey = Mid(Lne, LCase(Arg(3)), LCase(Arg(4)) - LCase(Arg(3)))
            If IsNumeric(Sortkey) = False then
                Set RE = new Regexp
                re.Pattern = "[^0-9\.,]"
                re.global = true
                re.ignorecase = true
                Sortkey = re.replace(Sortkey, "")
            End If
            If IsNumeric(Sortkey) = False then
                Sortkey = 0
            ElseIf Sortkey = "" then
                Sortkey = 0
            ElseIf IsNull(Sortkey) = true then
                Sortkey = 0
            End If
            .AddNew
            .Fields("SortKey").value = CSng(SortKey)
            .Fields("Txt").value = Lne
            .UpDate
        Loop
        If LCase(Arg(2)) = "a" then SortColumn = "SortKey ASC"
        If LCase(Arg(2)) = "d" then SortColumn = "SortKey DESC"
        .Sort = SortColumn
        Do While not .EOF
            Outp.writeline .Fields("Txt").Value
            .MoveNext
        Loop
    End With

    ElseIf LCase(Arg(1)) = "d" then
    With rs
        .Fields.Append "SortKey", 4 
        .Fields.Append "Txt", 201, 5000 
        .Open
        Do Until Inp.AtEndOfStream
            Lne = Inp.readline
            SortKey = Mid(Lne, LCase(Arg(3)), LCase(Arg(4)) - LCase(Arg(3)))
            If IsDate(Sortkey) = False then
                Set RE = new Regexp
                re.Pattern = "[^0-9\\\-:]"
                re.global = true
                re.ignorecase = true
                Sortkey = re.replace(Sortkey, "")
            End If
            If IsDate(Sortkey) = False then
                Sortkey = 0
            ElseIf Sortkey = "" then
                Sortkey = 0
            ElseIf IsNull(Sortkey) = true then
                Sortkey = 0
            End If
            .AddNew
            .Fields("SortKey").value = CDate(SortKey)
            .Fields("Txt").value = Lne
            .UpDate
        Loop
        If LCase(Arg(2)) = "a" then SortColumn = "SortKey ASC"
        If LCase(Arg(2)) = "d" then SortColumn = "SortKey DESC"
        .Sort = SortColumn
        Do While not .EOF
            Outp.writeline .Fields("Txt").Value
            .MoveNext
        Loop
    End With


    ElseIf LCase(Arg(1)) = "t" then
    With rs
        .Fields.Append "SortKey", 201, 260 
        .Fields.Append "Txt", 201, 5000 
        .Open
        Do Until Inp.AtEndOfStream
            Lne = Inp.readline
            SortKey = Mid(Lne, LCase(Arg(3)), LCase(Arg(4)) - LCase(Arg(3)))
            .AddNew
            .Fields("SortKey").value = SortKey
            .Fields("Txt").value = Lne
            .UpDate
        Loop
        If LCase(Arg(2)) = "a" then SortColumn = "SortKey ASC"
        If LCase(Arg(2)) = "d" then SortColumn = "SortKey DESC"
        .Sort = SortColumn
        Do While not .EOF
            Outp.writeline .Fields("Txt").Value
            .MoveNext
        Loop
    End With
    ElseIf LCase(Arg(1)) = "tt" then
    With rs
        .Fields.Append "SortKey", 201, 260 
        .Fields.Append "Txt", 201, 5000 
        .Open
        Do Until Inp.AtEndOfStream
            Lne = Inp.readline
            SortKey = Trim(Mid(Lne, LCase(Arg(3)), LCase(Arg(4)) - LCase(Arg(3))))
            .AddNew
            .Fields("SortKey").value = SortKey
            .Fields("Txt").value = Lne
            .UpDate
        Loop
        If LCase(Arg(2)) = "a" then SortColumn = "SortKey ASC"
        If LCase(Arg(2)) = "d" then SortColumn = "SortKey DESC"
        .Sort = SortColumn
        Do While not .EOF
            Outp.writeline .Fields("Txt").Value
            .MoveNext
        Loop
    End With
    End If
End Sub

【讨论】:

    【解决方案2】:

    由于您使用的是字符串,因此您需要编写一个自定义排序函数来解析字符串中的测试数字。

    或者,您可以预处理列表并将数字解析为单独的字段,然后根据该字段进行排序。

    【讨论】:

      【解决方案3】:

      here 中的技术应用于问题(使用Split 而不是正则表达式):

      Option Explicit
      
      Dim aInp : aInp = Array( _
            "Test 1 pass dec 2" _
          , "Test 3 fail" _
          , "Test 2 pass jun 4" _
          , "Verified" _
          , "Test 10 pass" _
          , "User Accepted" _
      )
      WScript.Echo "----- Input:", vbCrLf & Join(aInp, vbCrLf)
      Dim aOtp : aOtp = Array( _
            "Test 1 pass dec 2" _
          , "Test 2 pass jun 4" _
          , "Test 3 fail" _
          , "Test 10 pass" _
          , "User Accepted" _
          , "Verified" _
      )
      WScript.Echo "----- Expected:", vbCrLf & Join(aOtp, vbCrLf)
      
      Dim oNAL : Set oNAL = CreateObject( "System.Collections.ArrayList" )
      Dim oSB  : Set oSB  = CreateObject( "System.Text.StringBuilder" )
      Dim sInp, aParts, aWTF
      For Each sInp In aInp
          aParts = Split(sInp, " ", 3)
          Select Case UBound(aParts)
            Case 0 ' add 2 blank elms to "verified"
              aWTF = aParts
              ReDim Preserve aWTF(2)
            Case 1 ' put an empty elm in the middle
              ' aParts = Array( aParts(0), "", aParts(1))
              ' ==> VBScript runtime error: This array is fixed or temporarily locked
              aWTF = Array( aParts(0), "", aParts(1))
            Case 2 ' What the doctor ordered
              aWTF = aParts
            Case Else
              Err.Raise "Shit hits fan"
          End Select
          oSB.AppendFormat_3 "{0}{1,4}{2}", aWTF(0), aWTF(1), aWTF(2)
          sInp = oSB.ToString() & "|" & sInp ' dirty trick: append org data th ease 'reconstruction'
          oSB.Length = 0
          oNAL.Add sInp
      Next
      oNAL.Sort
      
      ReDim aOut(oNAL.Count - 1)
      Dim i
      For i = 0 To UBound(aOut)
          aOut(i) = Split(oNAL(i), "|")(1)
      Next
      WScript.Echo "----- Output:", vbCrLf & Join(aOut, vbCrLf)
      

      输出:

      cscript 37946075.vbs
      ----- Input:
      Test 1 pass dec 2
      Test 3 fail
      Test 2 pass jun 4
      Verified
      Test 10 pass
      User Accepted
      ----- Expected:
      Test 1 pass dec 2
      Test 2 pass jun 4
      Test 3 fail
      Test 10 pass
      User Accepted
      Verified
      ----- Output:
      Test 1 pass dec 2
      Test 2 pass jun 4
      Test 3 fail
      Test 10 pass
      User Accepted
      Verified
      

      只是为了好玩:“相同”,但使用 RegExp(更好的缩放技术):

      ...
      Dim r    : Set r    = New RegExp
      r.Pattern = "^(\w+\s*)(\d+\s*)?(.*)$"
      Dim sInp, m, aParts(2)
      Dim i
      For Each sInp In aInp
          Set m = r.Execute(sInp)
          If 1 = m.Count Then
             For i = 0 To 2
                 aParts(i) = m(0).SubMatches(i)
             Next
           Else
              Err.Raise "Shit hits fan"
          End If
          oSB.AppendFormat_3 "{0}{1,4}{2}", aParts(0), aParts(1), aParts(2)
          sInp = oSB.ToString() & "|" & sInp ' dirty trick: append org data to ease 'reconstruction'
      ...
      

      【讨论】:

        猜你喜欢
        • 2021-02-13
        • 2012-11-14
        • 2018-04-02
        • 1970-01-01
        • 2021-07-23
        • 1970-01-01
        • 2016-01-03
        • 2013-03-06
        • 1970-01-01
        相关资源
        最近更新 更多