using System.Text.RegularExpressions;
namespace TestProject;
/// <summary>
/// 자연 정렬 비교자
/// </summary>
public class NaturalSortingComparer : IComparer<string>
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 정규 표현식
/// </summary>
private static readonly Regex _regex = new Regex(@"(?<=\D)(?=\d)|(?<=\d)(?=\D)", RegexOptions.Compiled);
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 비교하기 - Compare(source1, source2)
/// <summary>
/// 비교하기
/// </summary>
/// <param name="source1">소스 문자열 1</param>
/// <param name="source2">소스 문자열 2</param>
/// <returns>비교 결과</returns>
public int Compare(string source1, string source2)
{
source1 = source1.ToLower();
source2 = source2.ToLower();
if(string.Compare(source1, 0, source2, 0, Math.Min(source1.Length, source2.Length)) == 0)
{
if(source1.Length == source2.Length)
{
return 0;
}
return source1.Length < source2.Length ? -1 : 1;
}
string[] tokenArray1 = _regex.Split(source1);
string[] tokenArray2 = _regex.Split(source2);
int i = 0;
while(true)
{
int result = ComparePart(tokenArray1[i], tokenArray2[i]);
if(result != 0)
{
return result;
}
++i;
}
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 부분 비교하기 - ComparePart(source1, source2)
/// <summary>
/// 부분 비교하기
/// </summary>
/// <param name="source1">소스 문자열 1</param>
/// <param name="source2">소스 문자열 2</param>
/// <returns>비교 결과</returns>
private static int ComparePart(string source1, string source2)
{
int value1;
int value2;
if(int.TryParse(source1, out value1) && int.TryParse(source2, out value2))
{
return value1.CompareTo(value2);
}
return source1.CompareTo(source2);
}
#endregion
}