2016-06-21 2 views
2

Как сортировать строку с числовыми значениями с помощью VB Script?Сортировка строки с числами с помощью скрипта VB

Ниже приведены мои строки из каждой строки из таблицы:

  1. "Тест 1 проход разл 2"
  2. "Тест 3 провал"
  3. "Тест 2 прохода 4 июн"
  4. " Проверенный»
  5. "Тест 10 проход"
  6. "Пользователь Принимается"

Я хотел бы, чтобы хотелось получить в ниже порядке после сортировки (естественный порядок):

  1. "Тест 1 проход 2 декабря"
  2. "Тест 2 проходят 4 июня"
  3. "Тест 3 обанкротиться"
  4. «Тест 10 проход»
  5. «Пользователь Принимается»
  6. «Проверенный»

Пути я есть пытался до сих пор,

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

ArrayList был отсортирован в ниже порядке, основанном на ASCII, который я не предпочитаю:

  1. "Тест 1 проход разл 2"
  2. "Тест 10 проход"
  3. "Тест 2 проход 4 июня"
  4. "Тест 3 провал"
  5. "Пользователь Принято"
  6. «Проверенный»

Я попробовал эту ссылку Sort

и я понятия не имею, как использовать AppendFormat в моем случае.

Замечание: Моя заданная строка либо полностью строка, либо строка с числами (динамическая), поэтому не уверены, как использовать RecordSet или AppendFormat здесь, поскольку я новичок в программировании.

+1

Я смущен тем, что вы действительно здесь. Systems.Collections.ArrayList - это .Net-объект ... так что вы используете старый vbscript для работы с типами VB.Net? –

+0

Возможный дубликат [Натуральная сортировка с использованием сценария VB] (http://stackoverflow.com/questions/37928754/natural-sorting-using-vb-script) – Blackwood

ответ

0

У вас может быть другой пример.

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 
0

Поскольку вы работаете со строками, вы будете нуждаться, чтобы написать пользовательскую функцию сортировки, которая может анализировать число тестов из строк.

В качестве альтернативы, вы можете предварительно обработать свой список и проанализировать числа в отдельном поле, а затем отсортировать их на основе этого поля.

0

Чтобы применить технику из here задачи (с помощью Split вместо RegExp):

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 

Просто для удовольствия: The 'же', но с использованием 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' 
...