VBA修剪留下领先的空白

Posted

技术标签:

【中文标题】VBA修剪留下领先的空白【英文标题】:VBA Trim leaving leading white space 【发布时间】:2015-01-06 21:51:46 【问题描述】:

我正在尝试比较宏中的字符串,但输入的数据并不总是一致的。差异归结为前导空白的数量(即“test”与“test”与“test”)

对于我的宏,示例中的三个字符串应该是等价的。但是我不能使用替换,因为字符串中间的任何空格(例如“测试一二三”)都应该保留。我原以为这是 Trim 应该做的(以及删除所有尾随空格)。但是当我在字符串上使用 Trim 时,我看不出有什么不同,而且我肯定在字符串的前面留下了空白。

所以 A) Trim 在 VBA 中真正做了什么? B) 是否有我正在尝试做的内置函数,或者我只需要编写一个函数?

谢谢!

【问题讨论】:

Trim 确实删除了前导和尾随空格。你确定那是空间?试试Print Asc(Txt)看看ascii码是不是真的是32 您的数据在字符串的开头不包含空格(字符代码 32),或者您的代码执行不正确。 VBA Trim 函数在该函数的 VBA 帮助中有很好的描述。它与同名的 Worksheet 函数有些不同。 【参考方案1】:

所以正如 Gary 的学生所暗示的那样,这个角色不是 32 岁。实际上是 160 岁。现在我是一个简单的人,空白就是空白。因此,根据该观点,我创建了以下函数,该函数将删除所有不会实际显示给人眼的 Unicode 字符(即非特殊字符、非字母数字)。该函数如下:

Function TrueTrim(v As String) As String
Dim out As String
Dim bad As String
bad = "||127||129||141||143||144||160||173||" 'Characters that don't output something
       'the human eye can see based on http://www.gtwiki.org/mwiki/?title=VB_Chr_Values

out = v

'Chop off the first character so long as it's white space
If v <> "" Then
    Do While AscW(Left(out, 1)) < 33 Or InStr(1, bad, "||" & AscW(Left(out, 1)) & "||") <> 0 'Left(out, 1) = " " Or Left(out, 1) = Chr(9) Or Left(out, 1) = Chr(160)
        out = Right(out, Len(out) - 1)
    Loop

    'Chop off the last character so long as it's white space
    Do While AscW(Right(out, 1)) < 33 Or InStr(1, bad, "||" & AscW(Right(out, 1)) & "||") <> 0 'Right(out, 1) = " " Or Right(out, 1) = Chr(9) Or Right(out, 1) = Chr(160)
        out = Left(out, Len(out) - 1)
    Loop
End If 'else out = "" and there's no processing to be done

'Capture result for return
TrueTrim = out
End Function

【讨论】:

如果你要修剪数据,我会选择正则表达式解决方案,它更通用、更健壮 @Jeanno 下面的正则表达式解决方案没有捕捉到所有字符,这个解决方案做到了。【参考方案2】:

TRIM() 将删除所有前导空格

Sub demo()
    Dim s As String
    s = "   test   "
    s2 = Trim(s)
    msg = ""
    For i = 1 To Len(s2)
        msg = msg & i & vbTab & Mid(s2, i, 1) & vbCrLf
    Next i
    MsgBox msg
End Sub

您的数据可能包含不可见的字符,但也不是空格。

【讨论】:

原来是这样。我使用 Code(left(cellm 1)) 来获取角色(对于那些好奇的人来说是 160)。鉴于我继续创建了一个函数来清除前导空白(任何代码值小于 32、160 和少数其他值)。【参考方案3】:

没有看到你的代码很难知道,但你也可以使用 Application.WorksheetFunction.Clean() 方法和 Trim() 方法来删​​除不可打印的字符。

MSDN Reference page for WorksheetFunction.Clean()

【讨论】:

【参考方案4】:

您为什么不尝试使用 Instr 函数呢?像这样的

Function Comp2Strings(str1 As String, str2 As String) As Boolean
    If InStr(str1, str2) <> 0 Or InStr(str2, str1) <> 0 Then
        Comp2Strings = True
    Else
        Comp2Strings = False
    End If
End Function

基本上,您正在检查 string1 是否包含 string2 或 string2 是否包含 string1。这将始终有效,您不必修剪数据。

【讨论】:

Comp2Strings = (InStr(str1, str2) 0 或 InStr(str2, str1) 0) 这会因str1 = " test"str1 = "test " 而失败 根据 OP,只有一个字符串会有前导或尾随空格。所以这会工作 这会告诉我是否有前导空格(或取决于 str2 的空白字符)m 但我需要清理垃圾空间以供以后存储(抱歉在原始文件中没有引用它帖子,没有考虑它,因为我的问题是 InStr 返回 0,而在我的大脑中,它应该返回一个值 >0)【参考方案5】:

VBA 的 Trim 函数仅限于处理空格。它将删除字符串开头和结尾的空格。

为了处理换行符和制表符之类的问题,我总是导入 Microsoft VBScript RegEx 库并用它来替换空白字符。

在您的 VBA 窗口中,转到工具、参考,找到 Microsoft VBScript 正则表达式 5.5。检查它并点击确定。

然后您可以创建一个相当简单的函数来修剪所有空白,而不仅仅是空格。

Private Function TrimEx(stringToClean As String)
    Dim re As New RegExp
    ' Matches any whitespace at start of string
    re.Pattern = "^\s*"
    stringToClean = re.Replace(stringToClean, "")
    ' Matches any whitespace at end of string
    re.Pattern = "\s*$"
    stringToClean = re.Replace(stringToClean, "")
    TrimEx = stringToClean
End Function

【讨论】:

据我所知,这应该可行。我从来都不是正则表达式的粉丝,因为代码的密集程度太容易搞砸了。 这不适用于 OP 的问题。 \s 与 vbscript 中的 NBSP(字符代码 160)不匹配。不过,您可以使用像 [\s\xA0] 这样的正则表达式,并使用适当的行首和行尾锚点,并将多行设置为 true。【参考方案6】:

非打印文件划分网页的不同行。我分别用 X、Y 和 Z 替换它们。

Debug.Print Trim(Mid("X test", 2)) ' VBA 中第一名计为 2

Debug.Print Trim(Mid("XY test ", 3)) '第二名在VBA中计为3

Debug.Print Trim(Mid("X Y Z test ", 2)) ' 需要更多轮次 :)

程序员更喜欢大文本,因为可以使用内置工具(inSTR、Mid、Left 等)整齐地切割。使用来自多个孩子的文本(即使用 .textContent 与 .innerText)可能会导致处理一些不可打印的内容,但 DOM 和 REGEX 不适合初学者。精确地处理内部文本的子元素(子元素一个接一个!)可能有助于规避不可打印的字符。

【讨论】:

以上是关于VBA修剪留下领先的空白的主要内容,如果未能解决你的问题,请参考以下文章

如何修剪空白?

使用 PIL 动画 GIF 修剪空白

如何分解和修剪空白?

修剪空白而不影响字符串

字符串空白清理不是修剪[重复]

修剪列内的额外空白