regex - PowerShell将字符串切成两半
问题描述
我有由相同的一半组成的行,我想从中删除一半;例如,'AbcAbc'
应该变成'Abc'
.
数据总是看起来像:
10.22.20.106/tcp/8010.22.20.106/tcp/80
10.22.20.46/tcp/44310.22.20.46/tcp/443
10.22.20.90/tcp/44310.22.20.90/tcp/443
10.22.20.90/tcp/8010.22.20.90/tcp/80
10.22.20.89/tcp/44310.22.20.89/tcp/443
10.22.20.89/tcp/8010.22.20.89/tcp/80
10.22.20.29/tcp/44310.22.20.29/tcp/443
10.22.20.29/tcp/8010.22.20.29/tcp/80
10.22.20.122/tcp/44310.22.20.122/tcp/443
10.22.20.123/tcp/44310.22.20.123/tcp/443
10.22.20.79/tcp/44310.22.20.79/tcp/443
10.22.20.79/tcp/8010.22.20.79/tcp/80
10.22.20.78/tcp/44310.22.20.78/tcp/443
10.22.20.78/tcp/8010.22.20.78/tcp/80
10.22.20.74/tcp/44310.22.20.74/tcp/443
10.22.20.74/tcp/8010.22.20.74/tcp/80
10.22.20.22/tcp/44310.22.20.22/tcp/443
10.22.20.22/tcp/8010.22.20.22/tcp/80
10.22.20.99/tcp/44310.22.20.99/tcp/443
10.22.20.99/tcp/8010.22.20.99/tcp/80
10.22.20.54/tcp/44310.22.20.54/tcp/443
10.22.20.54/tcp/8010.22.20.54/tcp/80
我计算了字符串中的字符数,然后将其减半,但不确定如何使用计算出的(减半)字符数来剪切原始字符串。
$vip_ip = $vip_line.("Virtual IP Address/Protocol/Port")
$half_string = $vip_ip.length /2
$vip_ip.length 44
$half_string 22
$vip_cut = $vip_ip.(0,-$halfstring)
解决方案
马特的答案是要走的路,但只是提出一个基于正则表达式的替代方案-replace
,主要是作为一个有趣的实验:
注意:虽然这个解决方案很简洁,但在我的测试中它是模糊的,并且比.Substring()
基于 - 的方法慢 2-3 倍。
# Extract one half of the input string consisting of identical halves.
PS> '10.22.20.54/tcp/44310.22.20.54/tcp/443' -replace '^(.+)\1$', '$1'
10.22.20.54/tcp/443
正则表达式子表达式匹配字符串开头 ( ) 处的
^(.+)
一个或多个 (+
)(非换行符)字符 ( ),并在捕获组中捕获它们。.
^
(...)
\1$
匹配一个反向引用( ),它指的是(第一个也是唯一的)捕获组匹配的内容,位于字符串 ( )\1
的末尾。 实际上,只有当输入由相同的一半组成时,整个正则表达式才会匹配。$
$1
作为-regex
替换操作数,然后返回(第一个也是唯一的)捕获组匹配的内容,即输入字符串的前半部分。
请注意,这样的正则表达式效率低下,因为它需要大量回溯,因为事先不知道中点。
在这种情况下,使用非贪婪修饰符(+?
而不是+
)也可以,但实际上在性能方面似乎没有任何区别(推测使用.+?
then 需要相同数量的“前向跟踪”尝试)。