【问题标题】:How to replace only certain spaces in a string?如何仅替换字符串中的某些空格?
【发布时间】:2020-09-05 06:29:21
【问题描述】:

我为数据创建了一个导入函数。

有时导入字符串是这样的:

47588328 2020.06.25 11:42:13 买入 0.11 欧元 1.12240 1.11902 0.00000
2020.06.25 14:05:04 1.11902 0.00 0.00 0.00 -35.35

有时像这样

45881875
2020.05.25 19:53:14
buy
0.10
eurusd
1.08975
1.08999
1.09503
2020.05.26 10:49:17
1.09503
0.00
0.00
-0.48
51.14

我将值拆分为一个数组。如果字符串由换行符分隔,则没有问题。

如果字符串以空格分隔,我无法处理它。我试图用换行符替换空格。
这可行,但有日期和时间部分。它们必须保持在一起,当我用换行符替换空格时它们不会。

我有这个:

TextboxText = UserForm1.TextBox1.Text
TextboxText = Replace(TextboxText, " ", vbLf)

我的一个想法是构建一个遍历所有空格的循环,然后除了空格号 2 和 10。例如使用伪代码:

> For Each Space in TextboxText     
>     If Not space nr = 2 or space nr = 10 Then
>         replace space
>     End if 
> Next

【问题讨论】:

    标签: vba


    【解决方案1】:

    我会说像你一直在做的那样把它分成一个数组(大概使用split(strText)然后通过数组重新加入日期和时间。类似下面的东西

    For x = LBound(myArray) to Ubound(myArray)
        'If IsDate(myArray(x)) Then - This didn't work as would erroneously return TRUE for decimals
        If Format(Cdate(myArray(x)), "yyyy") <> "1899" Then
            MyArray(x) = MyArray(x) & " " & MyArray(x+1) 'Join it to the value after
            MyArray(x+1) = "" 'Delete the value after (time value)
        End If
    Next
    

    那么你之后对数组所做的任何事情都只需要包括例如If MyArray(x) &lt;&gt; "" 错过那些空值。

    【讨论】:

    • 我刚试过这个,即使在像“0.11”这样的字符串上,IsDate 似乎也返回 true - 很奇怪
    • 您好 Spencer Barnes 我真的很喜欢您的解决方案!非常性感:) 非常感谢您提出这个建议。我喜欢它,因为日期可以在字符串中的任何位置.. 但正如 jamheadart 所说,唯一的问题是它返回 true 的 IsDate 不仅有日期.. 你知道如何解决这个问题吗?问题是像“0.11”这样的值,它们被解释为日期,我们能以某种方式排除这个吗?也许使用正则表达式,但我不知道如何使用它们......
    • hmm ... 不得不说我并没有真正彻底地测试这个,只是它是我想到的第一个解决方案。忘记了它会将小数(0.11)解释为时间(在本例中为 00:11:00)所以,下一个修复;使用Cdate 而不是IsDate 来检查它实际上是日期而不是时间。现在只需将其编辑为答案...
    • @LucaS 如果有什么安慰的话,我什至从未听说过 Regex。我也刚刚想到了一种可能更简单的方法; If IsDate(myArray(x) &amp; " " &amp; myArray(x+1)) - 我认为可以使用它。选择你最喜欢的。
    • 你真漂亮 :) 我还找到了一个解决方案,可以对“?.??”进行额外检查像这样的模式 然后用 if TestCheck = False 语句进行测试。但我想你的解决方案更好。非常感谢你的帮助...做您认为可以从数组中删除这 2 个空值吗?但只有这2个值,因为可能还有其他空值......所以数组会完全相同,否则进一步处理会有点困难..
    【解决方案2】:

    这个直接返回一个字符串而不循环,但它也依赖于你的日期位置永远不会改变的前提和一个神奇的“&lt;dt&gt;”占位符字符串!

    Function GetSplit2(s As String) As String
    Dim x As Variant: x = Split(s, " ")
        s = Replace(s, x(1) & " " & x(2), x(1) & "<dt>" & x(2))
        s = Replace(s, x(9) & " " & x(10), x(9) & "<dt>" & x(10))
        s = Replace(s, " ", vbCrLf)
        GetSplit2 = Replace(s, "<dt>", " ")
    End Function
    

    这样使用:

    Sub test()
    Dim s As String: s = "47588328 2020.06.25 11:42:13 buy 0.11 eurusd 1.12240 1.11902 0.00000 2020.06.25 14:05:04 1.11902 0.00 0.00 0.00 -35.35"
    MsgBox GetSplit2(s)
    End Sub
    

    【讨论】:

      【解决方案3】:

      这并不像我最初希望的那样干净,我认为可能有更好的方法来做到这一点,但它确实有效:

      Function GetSplit(s As String) 
      Dim x As Variant: x = Split(s, " ")
      Dim r(13) As String
      Dim i As Long
      Dim j As Long
      For i = 0 To 15
          If i = 1 Or i = 9 Then
              r(j) = x(i) & " " & x(i + 1)
              i = i + 1
          Else
              r(j) = x(i)
          End If
          j = j + 1
      Next i
      GetSplit = r
      End Function
      

      它只是在一个由“”分割的数组中循环,并在相同位置的值之间移动,除非它们位于位置 1 或 9(空间 2 或 10),在这种情况下,它将第一个数组计数器连接并增加 1,用于像这样:

      Sub test()
      Dim s As String: s = "47588328 2020.06.25 11:42:13 buy 0.11 eurusd 1.12240 1.11902 0.00000 2020.06.25 14:05:04 1.11902 0.00 0.00 0.00 -35.35"
      Dim resultArray As Variant
          resultArray = GetSplit(s)
      End Sub
      

      当然,这一切只有在您每次获得的字符串格式完全相同的情况下才有效,我希望这些日期不要移动!

      编辑

      我尝试编辑这个以利用 IsDate 使其更具动态性,但 IsDate 对于其中的许多字符串返回 true,例如"0.11" 是一个日期,它甚至返回 false 作为实际日期(可能是由于区域设置)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-04
        • 1970-01-01
        • 2012-03-30
        • 2015-08-03
        • 2019-12-04
        • 2013-03-31
        • 1970-01-01
        • 2020-01-23
        相关资源
        最近更新 更多