String 一个特定字符在字符串中出现的次数

String 一个特定字符在字符串中出现的次数,string,powershell,String,Powershell,我一直在寻找一种方法来计算一个特定字符在字符串中出现的次数。我找到的所有方法都只计算字符“A”在字符串中总共出现的次数 Example of string: 0xAAABBC0123456789AABBCCDD0123456789ABCDEF 每个字符串长度为43个字符,以“0x”开头。每个字符串仅包含以下随机顺序的字符:0-9和A-F,总共16个不同的字符。每个字符可以在一行中依次出现多次,例如:“AAA”或111 我感兴趣的是一个字符串中最多16个字符中的每一个字符在后面出现的次数,并通过

我一直在寻找一种方法来计算一个特定字符在字符串中出现的次数。我找到的所有方法都只计算字符“A”在字符串中总共出现的次数

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也许我对这个标题的解释太过执着了。