diff --git a/AMWD.Common/Comparer/VersionStringComparer.cs b/AMWD.Common/Comparer/VersionStringComparer.cs
new file mode 100644
index 0000000..aa5e1b2
--- /dev/null
+++ b/AMWD.Common/Comparer/VersionStringComparer.cs
@@ -0,0 +1,86 @@
+using System;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+
+namespace AMWD.Common.Comparer
+{
+ ///
+ /// Defines a method to compare two strings.
+ ///
+#if NET8_0_OR_GREATER
+ public partial class VersionStringComparer : IComparer
+ {
+ private readonly Regex _versionRegex = VersionRegex();
+#else
+
+ public class VersionStringComparer : IComparer
+ {
+ private readonly Regex _versionRegex = new("([0-9.]+)");
+#endif
+
+ ///
+ /// Compares two strings and returns a value indicating
+ /// whether one is less than, equal to, or greater than the other.
+ ///
+ /// The first version string.
+ /// The second version string.
+ ///
+ /// A signed integer that indicates the relative values of x and y, as shown in the following table:
+ ///
+ ///
+ /// Value
+ /// Meaning
+ ///
+ /// -
+ /// -1
+ /// x is less than y
+ ///
+ /// -
+ /// 0
+ /// x equals y
+ ///
+ /// -
+ /// 1
+ /// x is greater than y
+ ///
+ ///
+ ///
+ public int Compare(string x, string y)
+ {
+ if (string.IsNullOrWhiteSpace(x) && string.IsNullOrWhiteSpace(y))
+ return 0;
+
+ if (string.IsNullOrWhiteSpace(x))
+ return -1;
+
+ if (string.IsNullOrWhiteSpace(y))
+ return 1;
+
+ string xMainVersion = _versionRegex.Match(x).Groups[1].Value;
+ string yMainVersion = _versionRegex.Match(y).Groups[1].Value;
+
+ string xAppendix = x.ReplaceStart(xMainVersion, "");
+ string yAppendix = y.ReplaceStart(yMainVersion, "");
+
+ if (xMainVersion.IndexOf('.') < 0)
+ xMainVersion += ".0";
+
+ if (yMainVersion.IndexOf('.') < 0)
+ yMainVersion += ".0";
+
+ var xVersion = Version.Parse(xMainVersion);
+ var yVersion = Version.Parse(yMainVersion);
+
+ int versionResult = xVersion.CompareTo(yVersion);
+ if (versionResult != 0)
+ return versionResult;
+
+ return xAppendix.CompareTo(yAppendix);
+ }
+
+#if NET8_0_OR_GREATER
+ [GeneratedRegex("([0-9.]+)")]
+ private static partial Regex VersionRegex();
+#endif
+ }
+}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4e8b6cc..cb6784f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `ArReader` and `ArWriter` for Unix archives
- `TarReader` and `TarWriter` for TAR archives
+- `VersionStringComparer` to compare version strings (SemVer)
### Changed
diff --git a/UnitTests/Common/Comparer/VersionStringComparerTests.cs b/UnitTests/Common/Comparer/VersionStringComparerTests.cs
new file mode 100644
index 0000000..a24d496
--- /dev/null
+++ b/UnitTests/Common/Comparer/VersionStringComparerTests.cs
@@ -0,0 +1,67 @@
+using AMWD.Common.Comparer;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace UnitTests.Common.Comparer
+{
+ [TestClass]
+ public class VersionStringComparerTests
+ {
+ [DataTestMethod]
+ [DataRow(null, "0")]
+ [DataRow("", "0")]
+ [DataRow("0", "1")]
+ [DataRow("1.0", "1.1")]
+ [DataRow("1.0.0", "1.0.1")]
+ [DataRow("1.0.0.0", "1.0.0.1")]
+ [DataRow("1.0.0.0-RC1", "1.0.0.0-RC2")]
+ public void ShouldBeLessThan(string x, string y)
+ {
+ // Arrange
+ var comparer = new VersionStringComparer();
+
+ // Act
+ int result = comparer.Compare(x, y);
+
+ // Assert
+ Assert.AreEqual(-1, result);
+ }
+
+ [DataTestMethod]
+ [DataRow("0", null)]
+ [DataRow("0", "")]
+ [DataRow("1", "0")]
+ [DataRow("1.1", "1.0")]
+ [DataRow("1.0.1", "1.0.0")]
+ [DataRow("1.0.0.1", "1.0.0.0")]
+ [DataRow("1.0.0.0-RC2", "1.0.0.0-RC1")]
+ public void ShouldBeGreaterThan(string x, string y)
+ {
+ // Arrange
+ var comparer = new VersionStringComparer();
+
+ // Act
+ int result = comparer.Compare(x, y);
+
+ // Assert
+ Assert.AreEqual(1, result);
+ }
+
+ [DataTestMethod]
+ [DataRow(null, null)]
+ [DataRow("", "")]
+ [DataRow("1", "1")]
+ [DataRow("1.2.3", "1.2.3")]
+ [DataRow("1.2.3-alpha", "1.2.3-alpha")]
+ public void ShouldBeEqual(string x, string y)
+ {
+ // Arrange
+ var comparer = new VersionStringComparer();
+
+ // Act
+ int result = comparer.Compare(x, y);
+
+ // Assert
+ Assert.AreEqual(0, result);
+ }
+ }
+}