简体   繁体   English

VBA 替换字符串 EXCEL 2019

[英]VBA replace a string EXCEL 2019

I cannot extract the postal/zip code of a given address cell that comes like this:我无法提取给定地址单元格的邮政编码,如下所示:

"108, avenue du Grand Sud 37 170 CHAMBRAY les TOURS". “108, avenue du Grand Sud 37 170 CHAMBRAY les TOURS”。

I have used:我用过:

=RECHERCHE(9^9;--("0"&STXT(A2;MIN(CHERCHE({0.1.2.3.4.5.6.7.8.9};A2&"0 123456789"));LIGNE($1:$100))))

Which sometimes works, sometimes not depending on the street number starting the address (here "108,").有时可行,有时不取决于地址开始的街道号码(此处为“108”)。

The problem is the space of the pattern "37 170".问题是模式“37 170”的空间。 I would like to remove the blank space in the pattern.我想删除模式中的空白。 Is there a regex way to search this pattern "## ###", and then to remove this poisonous blank space?有没有一种正则表达式方法来搜索这个模式“## ###”,然后删除这个有毒的空格?

Thank you for your tricks.谢谢你的诡计。

I have tried this piece of code:我试过这段代码:

Function toto(r, Optional u = 0)
Application.Volatile
Dim i%, j%, adr$, cp$, loca$, x
  x = Split(r)
  For i = 0 To UBound(x)
    If x(i) Like "#####" Then Exit For
  Next
  If i > UBound(x) Then
    adr = r.Value 'facultatif
  Else
    cp = x(i)
    For j = 0 To i - 1: adr = adr & x(j) & " ": Next
    adr = Left$(adr, Len(adr) + (Len(adr) > 1))
    For j = i + 1 To UBound(x): loca = loca & x(j) & " ": Next
    loca = Left$(loca, Len(loca) + (Len(loca) > 1))
  End If
  x = Array(adr, cp, loca)
  If 0 < u And u < 4 Then toto = x(u - 1) Else toto = x
End Function

The above code works fine for splitting addresses including street number, zip code, and city name.上面的代码适用于拆分地址,包括街道号码、zip 代码和城市名称。 But it does not work when the zip code is ## ### = 2 digit integer - space - 3 digit integer.但当 zip 代码为## ### = 2 位 integer - 空格 - 3 位 integer 时,它不起作用。

Edit: 01 June 2021编辑: 2021 年 6 月 1 日

Since it seems my question is not clear enough, let's rephrase:既然我的问题似乎不够清楚,让我们改写一下:

Given an Excel worksheet containing in each cell of column A, from saying A1 down to A10000, complete addresses like this one:给定一个 Excel 工作表,其中包含 A 列的每个单元格,从 A1 到 A10000,完整的地址如下:

"2 rue Rene cassin Centre Commercial Châlon 2 Sud 71 100 CHALON SUR SAONE" or this one: "15, Rue Emile Schwoerer 68 000 COLMAR" “2 rue Rene cassin Centre Commercial Châlon 2 Sud 71 100 CHALON SUR SAONE”或这个:“15, Rue Emile Schwoerer 68 000 COLMAR”

Where "71 100" and "68 000" are a zip code in incorrect format because of the extra space between the 2 first digits and 3 last digits.其中“71 100”和“68 000”是格式不正确的 zip 代码,因为前 2 个数字和最后 3 个数字之间有多余的空格。

I need to split the Ai cell content in order to obtain:我需要拆分 Ai 单元格内容以获得:

  • in cell Bi: the text (street, etc.) placed left before the 2 first digits of the "wrong" zip code,在单元格 Bi 中:文本(街道等)放在“错误”zip 代码的前 2 个数字之前的左侧,
  • in cell Ci: the zip code with its correct format ("71100" and not "71 100"),在单元格 Ci:zip 代码及其正确格式(“71100”而不是“71 100”),
  • in cell Di: the text (city name) after the zip code.在单元格 Di:zip 代码后的文本(城市名称)。

It's a kind of left and right extraction around the zip code.是围绕zip代码左右提取的一种。

The above code that I have posted does not work.我发布的上述代码不起作用。

In order to obtain the correct zip code format, I have tried the regex following function:为了获得正确的 zip 代码格式,我尝试了 function 之后的正则表达式:

Function FindReplaceRegex(rng As Range, reg_exp As String, replace As String)
    Set myRegExp = New RegExp
    myRegExp.IgnoreCase = False
    myRegExp.Global = True
    myRegExp.Pattern = reg_exp
    
    FindReplaceRegex = myRegExp.replace(rng.Value, replace)
End Function

But I am unable to determine the correct regular expression pattern to get rid of the space in the zip code.但我无法确定正确的正则表达式模式以消除 zip 代码中的空间。 PEH gave me the following pattern: PEH 给了我以下模式:

(.*)([0-9]{2}?[0-9]{3})(.*)

When using the function, I have tried to define the replacement pattern by:使用 function 时,我尝试通过以下方式定义替换模式:

(.*)([0-9]{2}[0-9]{3})(.*)

But it would not work.但这行不通。 Hope this will clarify my question.希望这能澄清我的问题。

Any idea is welcome.欢迎任何想法。 Thanks谢谢

If these input strings always have the same pattern, try:如果这些输入字符串始终具有相同的模式,请尝试:

=CONCAT(FILTERXML("<t><s>"&SUBSTITUTE(A1," ","</s><s>")&"</s></t>","//s[.*0=0]"))

在此处输入图像描述

Depending on your needs/edge-cases, you could add more xpath expressions.根据您的需要/边缘情况,您可以添加更多 xpath 表达式。

If this is VBA, I have a fix for you (please forgive the crappy naming convention, I'm scribbling this down in work while waiting for SQL to refresh):如果这是 VBA,我有一个解决方案(请原谅蹩脚的命名约定,我在等待 SQL 刷新时在工作中草草写下):

Sub test1()

a0 = Cells(1, 1)  'Get the text, in this case "108, avenue du Grand Sud 37 170 CHAMBRAY les TOURS"
aa = Replace(a0, ",", " ")  'Make all delimiters of same type, so removing commas, you may need to add more replace work here?
ab = Application.Trim(aa)  'Reduce all whitespace to single entries, i.e. " " rather than "  "
ac = Split(ab, " ", -1)  'Now split by that single whitespace entry

Dim txt()

i2 = 0
lastIsNumeric = False
For i1 = 0 To UBound(ac) - 1  'Step through each entry in our "split" list

    If IsNumeric(ac(i1)) = True And IsNumeric(ac(i1 + 1)) = True Then     
        'Two numbers back to back, join
        ReDim Preserve txt(i2)
        txt(i2) = ac(i1) + ac(i1 + 1)
        i2 = i2 + 1
        i1 = i1 + 1
    Else
        'Not two numbers back to back, don't join
        ReDim Preserve txt(i2)
        txt(i2) = ac(i1)
        i2 = i2 + 1
    
    End If

Next i1


If IsNumeric(ac(UBound(ac))) = False Then
    'Need to add last entry to txt()
    ReDim Preserve txt(UBound(txt) + 1)
    txt(UBound(txt)) = ac(UBound(ac))
End If

End Sub

edit 2021-06-01: The above will generate a list (txt) of all the entries within your address.编辑 2021-06-01:以上将生成您地址中所有条目的列表 (txt)。 You can then reassemble if you wish, or extract out the postcode only.然后,您可以根据需要重新组装,或仅提取邮政编码。

If you want it as a function, then it would be:如果您希望它是 function,那么它将是:

Public Function getPostcode(a0)

aa = Replace(a0, ",", " ")
ab = Application.Trim(aa)
ac = Split(ab, " ", -1)

Dim txt()

i2 = 0
lastIsNumeric = False
For i1 = 0 To UBound(ac) - 1
    If IsNumeric(ac(i1)) = True And IsNumeric(ac(i1 + 1)) = True Then
        'Two numbers back to back, join
        ReDim Preserve txt(i2)
        txt(i2) = ac(i1) + ac(i1 + 1)
        i2 = i2 + 1
        i1 = i1 + 1
    Else
        'Not two numbers back to back, don't join
        ReDim Preserve txt(i2)
        txt(i2) = ac(i1)
        i2 = i2 + 1
    
    End If

Next i1


If IsNumeric(ac(UBound(ac))) = False Then
    'Need to add last entry to txt()
    ReDim Preserve txt(UBound(txt) + 1)
    txt(UBound(txt)) = ac(UBound(ac))
End If

'Re-assemble string for return
rtnTxt = ""
For i1 = 0 To UBound(txt)
    rtnTxt = rtnTxt & " " & txt(i1)
Next i1

getPostcode = rtnTxt

End Function

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM