简体   繁体   English

用“_”替换每个奇数出现的空格

[英]Replace every odd occurrence of space with “_”

I have the following string where I should replace every odd occurrence of space with _ . 我有以下字符串,我应该用_替换每个奇数出现的空格。

String: 串:

901 R 902 M 903 Picture_message 904 NA 905 F 906 Local_Relay 907 46 
908 51705 909 306910001112/TYPE=PLMN@mms.cosmote.gr

Expected String: 预期字符串:

901_R 902_M 903_Picture_message 904_NA 905_F 906_Local_Relay 907_46 
908_51705 909_306910001112/TYPE=PLMN@mms.cosmote.gr

I tried taking the space count and also using regular expression occurrence but was not able to hit the mark. 我尝试使用空间计数并使用正则表达式,但无法达到标记。

Loop and keep a count of spaces found but only act on odd numbers: 循环并保持找到的空格数但仅对奇数进行操作:

Dim thing: thing = "901 R 902 M 903 Picture_message 904 NA 905 F 906 Local_Relay 907 46 908 51705 909 306910001112/TYPE=PLMN@mms.cosmote.gr"
Dim i, counter

For i = 1 To Len(thing)
    If Mid(thing, i, 1) = " " Then
        counter = counter + 1
        If counter Mod 2 Then thing = Left(thing, i - 1) & "_" & Mid(thing, i + 1)
    End If
Next

msgbox thing

One way is to split the string at spaces, append underscores to odd and spaces to even elements (except for the last one), then glue them back together: 一种方法是在空格处拆分字符串,将下划线附加到奇数和空格到偶数元素(最后一个除外),然后将它们粘合在一起:

s = "901 R 902 M 903 Picture_message 904 NA 905 F 906 Loc..."

a = Split(s, " ")

For i = 0 To UBound(a)-1 Step 2
  a(i) = a(i) & "_"
Next
For i = 1 To UBound(a)-1 Step 2
  a(i) = a(i) & " "
Next

WScript.Echo Join(a, "")

If you want to avoid looping twice you can do it in one go like this: 如果你想避免循环两次,你可以像这样一次完成:

s = "901 R 902 M 903 Picture_message 904 NA 905 F 906 Loc..."

c = CreateObject("ScriptingDictionary")
c.Add 0, "_"
c.Add 1, " "

a = Split(s, " ")

For i = 0 To UBound(a)-1
  a(i) = a(i) & c(i Mod 2)
Next

WScript.Echo Join(a, "")

If you still want to use a Regular Expression 如果您仍想使用正则表达式

Update: Have improved the pattern matching so only white-space characters are detected, so if the data contained 902 R it would still return 902_R . 更新:改进了模式匹配,因此只检测到空白字符,因此如果数据包含902 R它仍将返回902_R

Dim data: data = "901 R 902 M 903 Picture_message 904 NA 905 F 906 Local_Relay 907 46 908 51705 909 306910001112/TYPE=PLMN@mms.cosmote.gr"
'Include value of first capture group (\b\d{3})
'and append _ to it, this will make up the replacement value.
Dim value: value = "$1_"
Dim result
Dim rx: Set rx = new RegExp

With rx
  .Global = True
  .IgnoreCase = True
  'Expression checks for word boundary followed by 3 digit value
  'followed by any number whitespace characters.
  .Pattern = "(\b\d{3})\s+"
  result = .Replace(data, value)
End With
Set rx = Nothing

WScript.Echo "--------- Test ----------"
WScript.Echo data
WScript.Echo result
WScript.Echo

Output: 输出:

--------- Test ----------
901 R 902 M 903 Picture_message 904 NA 905 F 906 Local_Relay 907 46 908 51705 909 306910001112/TYPE=PLMN@mms.cosmote.gr
901_R 902_M 903_Picture_message 904_NA 905_F 906_Local_Relay 907_46 908_51705 909_306910001112/TYPE=PLMN@mms.cosmote.gr

Disclaimer: I actually missed the "odd" requirement in the question title, this example just uses pattern matching to find occurrences of the repeated pattern in the sample data <3 digit number><space> and Replace() it with the expected one <3 digit number><underscore> . 免责声明:我实际上错过了问题标题中的“奇怪”要求,这个例子只是使用模式匹配来查找样本数据<3 digit number><space>中的重复模式的出现,并将其Replace()与预期的<3 digit number><underscore>


Performance Considerations 性能注意事项

On a side note decided to test the performance against the classic For loop approach to show why I switched to using Regular Expressions for this type of the scenario, using @alex-k's example built a timing script that would also allow me to duplicate the source data multiple times to create a larger dataset. 在侧面说明决定测试性能与经典的For循环方法,以显示为什么我切换到使用正则表达式这种类型的场景,使用@ alex-k的 示例构建了一个时序脚本,也允许我复制源数据多次创建更大的数据集。

Duplicating the source 100 times 复制源100次

RegEx Method
String Length: 11999
Start: 55250.37109375
Stop: 55250.40234375
Diff: 0.03125

For loop - Mod Method
String Length: 11999
Start: 55250.40234375
Stop: 55250.4375
Diff: 0.03515625

A small increase at 1000 times 小幅增加1000倍

RegEx Method
String Length: 119999
Start: 55348.5859375
Stop: 55348.9375
Diff: 0.3515625

For loop - Mod Method
String Length: 119999
Start: 55348.9375
Stop: 55350.04296875
Diff: 1.10546875

But look what happens if we up that to 5000 times 但是看看如果我们把它增加到5000次会发生什么

RegEx Method
String Length: 599999
Start: 55545.69140625
Stop: 55547.4296875
Diff: 1.73828125

For loop - Mod Method
String Length: 599999
Start: 55547.4296875
Stop: 55584.15234375
Diff: 36.72265625

The effect on the For loop method is exponential to the point that when I get to 10000 times the RegEx method runs then fails to return in a timely manner when attempting to run the For loop method. For循环方法的影响是指数级的,当我达到10000次RegEx方法运行时,然后在尝试运行For循环方法时无法及时返回。

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

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