Сравнение двух строк не работает

У меня проблема со сравнением двух версий.

PS C:\Windows\system32> $soft.DisplayVersion -lt "124.0"
False

Я ожидаю, что он вернет True, потому что значение $soft.DisplayVersion равно:

PS C:\Windows\system32> $soft.DisplayVersion
95.0

Тип объекта:

PS C:\Windows\system32> $soft.DisplayVersion.GetType()

IsPublic IsSerial Name                                     BaseType                                                                                                                                                            
-------- -------- ----                                     --------                                                                                                                                                            
True     True     String  

Я также попробовал это:

PS C:\Windows\system32> $soft.DisplayVersion -lt 124.0
False

Я не знаю, поможет ли это, но $soft.DisplayVersion происходит из этого:

Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object DisplayName -match "Mozilla Firefox" 

Дайте мне знать, если вам нужна дополнительная информация, чтобы понять мою проблему.

Вы сравниваете строку со строкой, а это не то же самое, что сравнение с числами. Попробуйте: [десятичное]$soft.DisplayVersion -lt 124.0

jdweng 27.03.2024 13:13

Или 124.0 -ge $soft.DisplayVersion

js2010 27.03.2024 13:21

Почему это сработает: 124.0 -ge $soft.DisplayVersion а не это: $soft.DisplayVersion -lt 124.0

S. Me 27.03.2024 13:33

Вторая вещь преобразуется в число.

js2010 27.03.2024 13:47

Второй параметр ($soft.DisplayVersion) преобразуется в число? И вы не можете сравнивать -lt String и Number?

S. Me 27.03.2024 13:52

@S.Me Аргумент справа будет преобразован в тип аргумента слева, поэтому <Number> + <String> оценивается как <Number> + <String converted to Number>

Mathias R. Jessen 27.03.2024 14:13

124.0 — это число, поэтому второй элемент $soft.DisplayVersion автоматически преобразуется в тот же тип, что и первый элемент.

jdweng 27.03.2024 14:20

Хотя это будет исключением 1.0 -lt '1.0.1'

js2010 27.03.2024 15:14

@jdweng: Нет: поскольку левая часть — это строка, а правая — число, число преобразуется в строку; попробуй '2' -gt 10

mklement0 27.03.2024 15:24
В чем разница между методом "==" и equals()
В чем разница между методом "==" и equals()
Это один из наиболее часто задаваемых вопросов новичкам на собеседовании. Давайте обсудим его на примере.
Замена символа по определенному индексу в JavaScript
Замена символа по определенному индексу в JavaScript
В JavaScript существует несколько способов заменить символ в строке по определенному индексу.
0
9
64
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я буду использовать этот синтаксис:

[version]$soft.DisplayVersion -lt [version]"124.0.1"


PS C:\Windows\system32> [version]$soft.DisplayVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
124    0      1      -1      



PS C:\Windows\system32> 

Спасибо @lit и @mklement0, это идеально :)

Ответ принят как подходящий

Исходный ключ реестра и операнд сравнения подразумевают, что вы имеете дело с номерами версий.

Чтобы осмысленно сравнивать номера версий на основе их строковых представлений, приведите их к [version]:

[version] $soft.DisplayVersion -lt [version] '124.0'

Примечание:

  • Для краткости вы можете опустить приведение RHS [version], потому что приведение LHS неявно принудит и RHS тоже сделать [version]. Однако использование его с обеих сторон может помочь концептуальной ясности.

  • Для успешного приведения [версия] входная строка должна содержать не менее 2 компонентов (например, [version] '124.0' и не более 4 (например, [version] '124.0.1.2'), и каждый компонент должен быть положительным десятичным целым числом (включая 0).

  • [version] не способен анализировать семантические номера версий, которые ограничены тремя компонентами и могут содержать нечисловые суффиксы (например, 7.5.0-preview.2).


Что касается того, что вы пробовали:

  • $soft.DisplayVersion -lt "124.0" и $soft.DisplayVersion -lt 124.0 эквивалентны, и ни один из них не работает должным образом:

    • Поскольку операнд LHS является строкой, -lt приводит и операнд RHS к строке, а затем выполняет лексическое сравнение, а это не то, что вам нужно: '95.0' -lt '124.0''95.0' -lt 124.0 оба являются ложными, поскольку символ '9' больше, чем символ '1'.
  • [decimal]$soft.DisplayVersion -lt 124.0 (из ваш собственный ответ) работает только для строк номера версии до двух компонентов; например [decimal] '95.0.1' сломался бы.

Просто обратите внимание, что приведение завершится неудачей, если строка не использует форматирование семантической версии («Major.Minor.Build.Revision», все они только числа).

sirtao 27.03.2024 14:57

Приведение правой версии будет автоматическим, но это, безусловно, улучшит читаемость.

js2010 27.03.2024 15:08

Спасибо, @sirtao; на самом деле вы описываете ограниченный формат, поддерживаемый [version], который отличается от семантических номеров версий. Пожалуйста, посмотрите мое обновление для разъяснений.

mklement0 27.03.2024 15:16
[semver]'7.5.0-preview.2'Я этого не знала.
js2010 27.03.2024 15:19

Я не знал о '[semver]`, круто, спасибо

sirtao 27.03.2024 15:53

Здравствуйте, спасибо, что нашли время все это объяснить! Это именно то, что мне нужно, и теперь у меня есть следующее: ``` [версия]$soft.DisplayVersion -lt [версия]"124.0.1"```

S. Me 28.03.2024 09:49

Другие вопросы по теме