Có cách nào để nhận chuỗi con phù hợp từ chuỗi bằng cách so sánh bình đẳng văn hóa nhạy cảm không? Ví dụ, dưới văn hóa en-US, æ
và ae
được coi là bằng nhau. "Encyclopædia".IndexOf("aed")
đánh giá là 8
, biểu thị kết quả phù hợp; Tuy nhiên, có cách nào để trích xuất chuỗi con phù hợp, æd
, không liên quan đến việc lặp qua chuỗi nguồn không? Lưu ý rằng độ dài của các bề mặt tìm kiếm và kết hợp có thể khác nhau bởi một vài ký tự.Nhận chuỗi con từ chuỗi sử dụng so sánh văn hóa nhạy cảm
6
A
Trả lời
2
Tôi đã giải quyết điều này bằng cách trước tiên gọi số IndexOf
để nhận vị trí bắt đầu của trận đấu, sau đó lặp lại cố gắng xác định độ dài của nó. Tôi đã tối ưu hóa cho đường dẫn nóng của trận đấu có cùng chiều dài với chuỗi con được chỉ định; trong trường hợp đó, chỉ có một so sánh duy nhất được thực hiện.
public static class StringExtensions
{
public static void Find(this string source, string substring, StringComparison comparisonType, out int matchIndex, out int matchLength)
{
Find(source, substring, 0, source.Length, comparisonType, out matchIndex, out matchLength);
}
public static void Find(this string source, string substring, int searchIndex, StringComparison comparisonType, out int matchIndex, out int matchLength)
{
Find(source, substring, searchIndex, source.Length - searchIndex, comparisonType, out matchIndex, out matchLength);
}
public static void Find(this string source, string substring, int searchIndex, int searchLength, StringComparison comparisonType, out int matchIndex, out int matchLength)
{
matchIndex = source.IndexOf(substring, searchIndex, searchLength, comparisonType);
if (matchIndex == -1)
{
matchLength = -1;
return;
}
matchLength = FindMatchLength(source, substring, searchIndex, searchLength, comparisonType, matchIndex);
// Defensive programming, but should never happen
if (matchLength == -1)
matchIndex = -1;
}
private static int FindMatchLength(string source, string substring, int searchIndex, int searchLength, StringComparison comparisonType, int matchIndex)
{
int matchLengthMaximum = searchLength - (matchIndex - searchIndex);
int matchLengthInitial = Math.Min(substring.Length, matchLengthMaximum);
// Hot path: match length is same as substring length.
if (Compare(source, matchIndex, matchLengthInitial, substring, 0, substring.Length, comparisonType) == 0)
return matchLengthInitial;
int matchLengthDecrementing = matchLengthInitial - 1;
int matchLengthIncrementing = matchLengthInitial + 1;
while (matchLengthDecrementing >= 0 || matchLengthIncrementing <= matchLengthMaximum)
{
if (matchLengthDecrementing >= 0)
{
if (Compare(source, matchIndex, matchLengthDecrementing, substring, 0, substring.Length, comparisonType) == 0)
return matchLengthDecrementing;
matchLengthDecrementing--;
}
if (matchLengthIncrementing <= matchLengthMaximum)
{
if (Compare(source, matchIndex, matchLengthIncrementing, substring, 0, substring.Length, comparisonType) == 0)
return matchLengthIncrementing;
matchLengthIncrementing++;
}
}
// Should never happen
return -1;
}
private static int Compare(string strA, int indexA, int lengthA, string strB, int indexB, int lengthB, StringComparison comparisonType)
{
switch (comparisonType)
{
case StringComparison.CurrentCulture:
return CultureInfo.CurrentCulture.CompareInfo.Compare(strA, indexA, lengthA, strB, indexB, lengthB, CompareOptions.None);
case StringComparison.CurrentCultureIgnoreCase:
return CultureInfo.CurrentCulture.CompareInfo.Compare(strA, indexA, lengthA, strB, indexB, lengthB, CompareOptions.IgnoreCase);
case StringComparison.InvariantCulture:
return CultureInfo.InvariantCulture.CompareInfo.Compare(strA, indexA, lengthA, strB, indexB, lengthB, CompareOptions.None);
case StringComparison.InvariantCultureIgnoreCase:
return CultureInfo.InvariantCulture.CompareInfo.Compare(strA, indexA, lengthA, strB, indexB, lengthB, CompareOptions.IgnoreCase);
case StringComparison.Ordinal:
return CultureInfo.InvariantCulture.CompareInfo.Compare(strA, indexA, lengthA, strB, indexB, lengthB, CompareOptions.Ordinal);
case StringComparison.OrdinalIgnoreCase:
return CultureInfo.InvariantCulture.CompareInfo.Compare(strA, indexA, lengthA, strB, indexB, lengthB, CompareOptions.OrdinalIgnoreCase);
default:
throw new ArgumentException("The string comparison type passed in is currently not supported.", nameof(comparisonType));
}
}
}
sử dụng mẫu:
int index, length;
source.Find(remove, StringComparison.CurrentCulture, out index, out length);
string clean = index < 0 ? source : source.Remove(index, length);
Các vấn đề liên quan
- 1. So sánh chuỗi không nhạy cảm?
- 2. Chuỗi nhạy cảm trong trường hợp SQL So sánh
- 3. Trường hợp so sánh chuỗi VB6 không nhạy cảm?
- 4. cách tạo bộ lọc $ góc để lọc bộ so sánh chuỗi trường hợp nhạy cảm
- 5. Làm cách nào để làm cho trường hợp so sánh chuỗi của tôi không nhạy cảm?
- 6. chuỗi So sánh sử dụng '==' và 'là'
- 7. Chức năng ParseFloat nhạy cảm về văn hóa trong JavaScript?
- 8. Khi vượt qua Văn hóa khi so sánh chuỗi sử dụng Assert.AreEqual() trong C#
- 9. So sánh chuỗi trong .Net: "+" so với "-"
- 10. Chuỗi LINQ chứa một trường hợp chuỗi không nhạy cảm
- 11. Hiểu hành vi so sánh chuỗi
- 12. Trường hợp hoạt động chuỗi .NET có nhạy cảm không?
- 13. So sánh chuỗi PostgreSQL
- 14. văn bản jquery() không so sánh với chuỗi
- 15. So sánh chuỗi PHP bằng cách sử dụng '=='
- 16. So sánh chuỗi Bash
- 17. Hiệu suất so sánh SQL sử dụng chuỗi con vs giống với ký tự đại diện
- 18. So sánh mọi biểu tượng * của chuỗi văn bản
- 19. Trong VBA loại bỏ sự nhạy cảm khi so sánh các từ?
- 20. chuỗi so sánh phần
- 21. so sánh chuỗi bash
- 22. Hãy so sánh hai chuỗi sử dụng Regex
- 23. Case-nhạy cảm PowerShell thay
- 24. C# - So sánh các chuỗi mã hóa khác nhau
- 25. Kỹ thuật so sánh chuỗi Được sử dụng bởi Python
- 26. So sánh chuỗi trong AngularJS
- 27. iOS Core Data làm thế nào để so sánh đúng chuỗi văn bản bằng cách sử dụng vị từ?
- 28. sử dụng lodash để tìm chuỗi con từ mảng chuỗi
- 29. Cách so sánh con trỏ với các chuỗi trong C
- 30. So sánh chuỗi trong Rust
gì về việc sử dụng một biểu thức chính quy như '(ae | æ) d'? – juharr
@juharr: Regex sẽ là quá mức cần thiết (và giới thiệu các sắc thái riêng của nó). Tôi cần điều này để thực hiện chức năng rất đa năng, chẳng hạn như phương thức mở rộng 'String.Replace' nhạy cảm về văn hóa. – Douglas
Câu hỏi liên quan: [Làm cách nào để tôi có thể thực hiện thao tác "bắt đầu bằng" nhạy cảm với văn hóa từ giữa một chuỗi?] (Http://stackoverflow.com/q/15980310/1149773) (bởi Jon Skeet), [Độ dài của chuỗi con phù hợp với phương thức 'String.IndexOf' nhạy cảm về văn hóa] (http://stackoverflow.com/q/20480016/1149773). – Douglas