String 一个特定字符在字符串中出现的次数
我一直在寻找一种方法来计算一个特定字符在字符串中出现的次数。我找到的所有方法都只计算字符“A”在字符串中总共出现的次数String 一个特定字符在字符串中出现的次数,string,powershell,String,Powershell,我一直在寻找一种方法来计算一个特定字符在字符串中出现的次数。我找到的所有方法都只计算字符“A”在字符串中总共出现的次数 Example of string: 0xAAABBC0123456789AABBCCDD0123456789ABCDEF 每个字符串长度为43个字符,以“0x”开头。每个字符串仅包含以下随机顺序的字符:0-9和A-F,总共16个不同的字符。每个字符可以在一行中依次出现多次,例如:“AAA”或111 我感兴趣的是一个字符串中最多16个字符中的每一个字符在后面出现的次数,并通过
Example of string:
0xAAABBC0123456789AABBCCDD0123456789ABCDEF
每个字符串长度为43个字符,以“0x”开头。每个字符串仅包含以下随机顺序的字符:0-9和A-F,总共16个不同的字符。每个字符可以在一行中依次出现多次,例如:“AAA”或111
我感兴趣的是一个字符串中最多16个字符中的每一个字符在后面出现的次数,并通过我的所有字符串检查这一点
到目前为止,我只想到了这个Powershell脚本,它计算每行中每个角色出现的次数:
Get-Content " C:\Temp\strings.txt" | ForEach-Object{
New-Object PSObject -Property @{
Strings = $_
Row = $_.ReadCount
9 = [regex]::matches($_,"9").count
D = [regex]::matches($_,"D").count
B = [regex]::matches($_,"B").count
C = [regex]::matches($_,"C").count
7 = [regex]::matches($_,"7").count
3 = [regex]::matches($_,"3").count
1 = [regex]::matches($_,"1").count
8 = [regex]::matches($_,"8").count
F = [regex]::matches($_,"F").count
2 = [regex]::matches($_,"2").count
4 = [regex]::matches($_,"4").count
E = [regex]::matches($_,"E").count
6 = [regex]::matches($_,"6").count
5 = [regex]::matches($_,"5").count
A = [regex]::matches($_,"A").count
0 = [regex]::matches($_,"0").count
}
} | Sort Count -Descending | Export-Csv -Path "C:\Temp\output.csv" –NoTypeInformation
我更愿意在Powershell中执行此操作,但如果有其他更容易执行此操作的方法,请告诉我。一种方法是逐个字符迭代源字符串,并跟踪该字符的显示次数。这可以通过哈希表轻松完成。这样,
# Hashtable initialization. Add keys for 0-9A-F:
# Each char has initial count 0
$ht = @{}
"ABCDEF0123456789".ToCharArray() | % {
$ht.Add($($_.ToString()), 0)
}
# Test data, the 0x prefix will contain one extra zero
$s = "0xAAABBC0123456789AABBCCDD0123456789ABCDEF"
# Convert data to char array for iteration
# Increment value in hashtable by using the char as key
$s.ToCharArray() | % { $ht[$_.ToString()]+=1 }
# Check results
PS C:\> $ht
Name Value
---- -----
B 5
3 2
5 2
x 1
9 2
2 2
8 2
0 3
1 2
E 1
7 2
F 1
6 2
4 2
D 3
A 6
C 4
构建一个十六进制对,迭代字符串位置以忽略最后一个位置,并使用该十六进制对作为键在哈希表中增加一个值
$String = '0xAAABBC0123456789AABBCCDD0123456789ABCDEF'
$Hash=@{}
for ($i=2;$i -le ($string.length-2);$i++){
$Hash[$($String.Substring($i,2))]+=1
}
$Hash.GetEnumerator()|ForEach-Object{
[PSCustomObject]@{HexPair = $_.Name
Count = $_.Value}
} |Sort Count -Descending
样本输出
HexPair Count
------- -----
BC 3
AB 3
AA 3
CD 2
BB 2
9A 2
89 2
78 2
67 2
56 2
45 2
34 2
23 2
12 2
01 2
EF 1
DE 1
DD 1
D0 1
CC 1
C0 1
替代输出:
$Hash.GetEnumerator()|ForEach-Object{
[PSCustomObject]@{HexPair = $_.Name
Count = $_.Value}
} |Sort HexPair|group Count |%{"Count {0} {1}" -f $_.Name,($_.Group.HexPair -Join(', '))}|Sort
您可以使用lookback和backreference将字符串拆分为重复组:
$s = '0xAAABBC0123456789AABBCCDD0123456789ABCDEF'
$repeats = $s.Remove(0, 2) -split '(?<=(.))(?!\1|$)'
最后获取每个字符的最长序列:
'0123456789ABCDEF'.ToCharArray() |%{
[pscustomobject]@{
Character = "$_"
MaxLength = "$($groups[$_] |Sort Length -Descending |Select -First 1)".Length
}
}
最后,您应该为您的示例列出如下列表:
Character MaxLength
--------- ---------
0 1
1 1
2 1
3 1
4 1
5 1
6 1
7 1
8 1
9 1
A 3
B 2
C 2
D 2
E 1
F 1
function count_dups ($string){
$out=@() # null array
$out+="Character,Count" # header
$out+='0123456789ABCDEF'.ToCharArray()|%{"$_," + ($string.split("$_")|Where-object{$_ -eq ""}).count}
return ConvertFrom-Csv $out | sort count -Descending
}
结果是这样的,即使它给了我15行额外的字符串,我可以很容易地过滤出不需要的材料在微软Excel
#Removed all "0x" in textfile before running this script
$strings = Get-Content " C:\Temp\strings_without_0x.txt"
foreach($s in $strings) {
$repeats = $s.Remove(0, 2) -split '(?<=(.))(?!\1|$)'
$groups = $repeats |Group-Object {$_[0]} -AsHashTable
'0123456789ABCDEF'.ToCharArray() |%{
[pscustomobject]@{
String = "$s"
Character = "$_"
MaxLength = "$($groups[$_] |Sort Length -Descending |Select -First 1)".Length
}
} | Sort Count -Descending | Export-Csv -Path "C:\Temp\output.csv" -NoTypeInformation -Append}
谢谢你的回答 试试这个
$out=@()
$string="0xAAABBC0123456789AABBCCDD0123456789ABCDEF"
$out+="Character,Count"
$out+='0123456789ABCDEF'.ToCharArray()|%{"$_," + ($string.split("$_")|Where-object{$_ -eq ""}).count}
ConvertFrom-Csv $out |sort count -Descending
这将产生以下结果:
Character Count
--------- -----
A 3
B 2
0 1
C 1
D 1
F 1
1 0
2 0
3 0
4 0
5 0
6 0
7 0
8 0
9 0
E 0
您可以将其放入如下函数中:
Character MaxLength
--------- ---------
0 1
1 1
2 1
3 1
4 1
5 1
6 1
7 1
8 1
9 1
A 3
B 2
C 2
D 2
E 1
F 1
function count_dups ($string){
$out=@() # null array
$out+="Character,Count" # header
$out+='0123456789ABCDEF'.ToCharArray()|%{"$_," + ($string.split("$_")|Where-object{$_ -eq ""}).count}
return ConvertFrom-Csv $out | sort count -Descending
}
我在这里做的最大的部分就是这一行
'0123456789ABCDEF'.ToCharArray()|%{"$_," + (string.split("$_")|Where-object{$_ -eq ""}).count}
我正在将字符串拆分为从字符数组“0123456789ABCDEF”输入的字符上的数组。然后我计算数组中的空元素
我只是创建数组$out,以便输出可以像您的示例一样格式化。类似的想法,但我认为不应该计算0x。非常确定OP对重复字符的计数很感兴趣,而不是pairs@MathiasR.Jessen也许我对这个标题的解释太过执着了。