是否有 function/WinAPI 以不区分大小写的语言方式判断一个字符串是否以另一个字符串开头?
Is there a function/WinAPI to tell if one string starts with another string in a case-insensitive linguistic way?
说明我的问题的最佳方式是使用此示例(如果我使用 strstr
CRT 函数则不起作用):
const wchar_t* s1 = L"Hauptstraße ist die längste";
const wchar_t* s2 = L"Hauptstrasse";
bool b_s1_starts_with_s2 = !!wcsstr(s1, s2);
_ASSERT(b_s1_starts_with_s2); //Should be true
到目前为止,似乎识别语言字符串等效性的唯一 WinAPI 是 CompareStringEx
与 LINGUISTIC_IGNORECASE
标志一起使用时,但用于此目的有点棘手且效率低下,因为我将在 s2
上重复调用它,直到我到达终点。
所以我想知道是否有更好的方法(在 Windows 下)?
编辑:我的意思是:
bool b_s1_starts_with_s2 = false;
int ln1 = (int)wcslen(s1);
int ln2 = (int)wcslen(s2);
for(int p = 1; p <= ln1; p++)
{
if(::CompareString(LOCALE_USER_DEFAULT, LINGUISTIC_IGNORECASE,
s1, p,
s2, ln2) == CSTR_EQUAL)
{
//Match
b_s1_starts_with_s2 = true;
break;
}
}
我没有尝试过,但我认为您可能可以使用 LCMapStringEx
将所有字符串转换为适合语言环境的小写字母,然后使用 wcsncmp
进行正常的字符串前缀匹配。
(如评论中所述,您在示例中使用 wcsstr
毫无意义,因为 wcsstr
确定一个字符串是否包含另一个字符串。要确定一个字符串是否以另一个字符串开头,使用 wcsncmp
和前缀字符串的长度会更有效。)
您可以使用 FindNLSString
,检查 return 值是否为零。
显然它匹配 ß
和 ss
const wchar_t *s1 = L"Hauptstraße ist die längste";
const wchar_t *s2 = L"Hauptstrasse";
INT found = 0;
int start = FindNLSString(0, LINGUISTIC_IGNORECASE, s1, -1, s2, -1, &found);
wprintf(L"start = %d\n", start);
s1 = L"δεθ Testing Greek";
s2 = L"ΔΕΘ";
start = FindNLSString(0, LINGUISTIC_IGNORECASE, s1, -1, s2, -1, &found);
wprintf(L"start = %d\n", start);
说明我的问题的最佳方式是使用此示例(如果我使用 strstr
CRT 函数则不起作用):
const wchar_t* s1 = L"Hauptstraße ist die längste";
const wchar_t* s2 = L"Hauptstrasse";
bool b_s1_starts_with_s2 = !!wcsstr(s1, s2);
_ASSERT(b_s1_starts_with_s2); //Should be true
到目前为止,似乎识别语言字符串等效性的唯一 WinAPI 是 CompareStringEx
与 LINGUISTIC_IGNORECASE
标志一起使用时,但用于此目的有点棘手且效率低下,因为我将在 s2
上重复调用它,直到我到达终点。
所以我想知道是否有更好的方法(在 Windows 下)?
编辑:我的意思是:
bool b_s1_starts_with_s2 = false;
int ln1 = (int)wcslen(s1);
int ln2 = (int)wcslen(s2);
for(int p = 1; p <= ln1; p++)
{
if(::CompareString(LOCALE_USER_DEFAULT, LINGUISTIC_IGNORECASE,
s1, p,
s2, ln2) == CSTR_EQUAL)
{
//Match
b_s1_starts_with_s2 = true;
break;
}
}
我没有尝试过,但我认为您可能可以使用 LCMapStringEx
将所有字符串转换为适合语言环境的小写字母,然后使用 wcsncmp
进行正常的字符串前缀匹配。
(如评论中所述,您在示例中使用 wcsstr
毫无意义,因为 wcsstr
确定一个字符串是否包含另一个字符串。要确定一个字符串是否以另一个字符串开头,使用 wcsncmp
和前缀字符串的长度会更有效。)
您可以使用 FindNLSString
,检查 return 值是否为零。
显然它匹配 ß
和 ss
const wchar_t *s1 = L"Hauptstraße ist die längste";
const wchar_t *s2 = L"Hauptstrasse";
INT found = 0;
int start = FindNLSString(0, LINGUISTIC_IGNORECASE, s1, -1, s2, -1, &found);
wprintf(L"start = %d\n", start);
s1 = L"δεθ Testing Greek";
s2 = L"ΔΕΘ";
start = FindNLSString(0, LINGUISTIC_IGNORECASE, s1, -1, s2, -1, &found);
wprintf(L"start = %d\n", start);