我需要清理一些单元格,只保留重要的单词以生成搜索索引。
例如。 “如何发出帐户恢复请求”将被修整为“发出帐户恢复请求”,因为“ How,To,An”将出现在要过滤掉的单词列表中。
另一个复杂之处在于,它也将使用法语和西班牙语,这意味着我必须处理像d'这样的分词。
到目前为止,我一直在尝试使用一个函数,但是它不适用于分词(d'),如果在同一单元格中列出了“ de”和“ des”,它将从DES中删除DE然后仅保留寂寞的S,因为DES不再被识别:
Function ClearWords(s As String, rWords As Range) As String
Static RX As Object
If RX Is Nothing Then
Set RX = CreateObject("VBScript.RegExp")
RX.Global = True
RX.IgnoreCase = True
End If
RX.Pattern = "\b" & Replace(Join(Application.Transpose(rWords), "|"), ".", "\.") & "\b"
ClearWords = Application.Trim(RX.Replace(s, ""))
End Function
答案 0 :(得分:0)
如果您打算支持英语,法语和其他欧洲语言,则可以利用我在Regular expression not working for at least one European character
,(?![×÷])[A-Za-zÀ-ÿ]
发布的正则表达式。这种模式应该与您需要支持的所有字母字符匹配。由于您将在VBA中使用它,因此用\uXXXX
实体替换文字扩展字母,并将其转换为单个字符类[A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]
([A-Za-zÀ-ÖØ-öø-ÿ]
带有文字字符)是有意义的
现在,您需要构建自定义边界。初始边界可以是字符串^
的开头,也可以是上述字母以外的其他任何字符(如果要完全模拟_
,还可以是数字和\b
)。由于您要替换,因此需要将这两种模式放入(^|[^A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF])
<捕获组中,并在替换模式中使用$1
来恢复值,以免丢失。尾随边界是除以上字母(或数字/ _
)和字符串末尾以外的任何字符。由于VBA regex支持先行,所以我们可以只使用负先行 (?![A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF])
。
将它们放在一起:
RX.Pattern = "(^|[^A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF])(?:" & Replace(Join(Application.Transpose(rWords), "|"), ".", "\.") & ")(?![A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF])"
ClearWords = Application.Trim(RX.Replace(s, "$1"))
请参见this regex demo。
要同时删除空格,请将"(^|[^A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF])(?:"
替换为(?:\s+|(^|[^A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]))(?:
。参见this regex demo。
奖金:您似乎需要转义这些单词才能在正则表达式中使用它们:
Dim regExEscape As New RegExp
With regExEscape
.pattern = "[-/\\^$*+?.()|[\]{}]"
.Global = True
.MultiLine = False
End With
只需确保您处理所有的单词而不是Replace(Join(Application.Transpose(rWords), "|"), ".", "\.")
。