Предпочтительный подход:
Самый простой способ для точного подсчета вхождений нескольких подстрок, вероятно:
- Construct шаблон регулярное выражение, которое совпадает по любому из подстроки
- Используйте оператора
-split
, чтобы разделить строку
- Подсчитайте количество строк и вычесть 1:
# Define the substrings and a sentence to test against
$Substrings = "a","an","the"
$Sentence = "a long long sentence to test the -split approach, anticipating false positives"
# Construct the regex pattern
# The \b sequence ensures "word boundaries" on either side of a
# match so that "a" wont match the a in "man" for example
$Pattern = "\b(?:{0})\b" -f ($Substrings -join '|')
# Split the string, count result and subtract 1
$Count = ($Sentence -split $Pattern).Count - 1
Выходы:
C:\> $Count
2
Как вы можете видеть, что это будет соответствовать и разделить на "а" и "", но не "ЭН" в «предвидя».
Я оставлю это преобразование в функцию упражнения для читателя
Примечание: , если начать кормить больше, чем просто простых ASCII строк в качестве входных данных, вы можете захотеть, чтобы избежать их, прежде чем используя их в схеме:
$Pattern = "\b(?:{0})\b" -f (($Substrings |ForEach-Object {[regex]::Escape($_)}) -join '|')
наивный подход:
Если вам неудобно использовать регулярные выражения, вы можете сделать предположение, что что-либо между двумя пробелами является «словом» (например, в вашем исходном примере), а затем перебирайте слова в предложении и проверяйте, есть ли массив содержит слово в вопросе (не наоборот):
$Substrings = "a","an","the"
$Sentence = (Read-Host "Enter a long sentence from a story book or novel: ").Split(" ")
$Counter = 0
foreach($Word in $Sentence){
if($Substrings -contains $Word){
$Counter++
}
}
Как suggested by Jeroen Mostert, вы также можете использовать HashTable. При этом вы можете отслеживать вхождения каждого слова, а не просто общее количество:
$Substrings = "a","an","the"
$Sentence = (Read-Host "Enter a long sentence from a story book or novel: ").Split(" ")
# Create hashtable from substrings
$Dictionary = @{}
$Substrings |ForEach-Object { $Dictionary[$_] = 0 }
foreach($Word in $Sentence){
if($Dictionary.ContainsKey($Word)){
$Dictionary[$Word]++
}
}
$Dictionary
'-contains' не работает таким образом. Вы спрашиваете, содержит ли разбитый массив весь массив слов, который вы указали, что явно не имеет (в нем содержатся слова, а не массив). Вы можете решить это с помощью цикла или более эффективно, сохранив список слов в качестве хэш-таблицы и проверив членство в этом. –
Спасибо за ваш быстрый ответ, так что вы говорите, что я должен сделать массив $ Array в хеш-таблицу? – SkullNerd