Я пытаюсь выяснить, существует ли в предложении полное слово, скажем test
, и мне хотелось бы сделать это без учета регистра. Я воспользовался возможностями регулярных выражений в C и использовал \b
в шаблоне. Вот программа
#include <regex.h>
#include <stdio.h>
#include <string.h>
int main() {
const char* hay = "This Is a TEst, or not!";
regex_t regex;
if (regcomp(®ex, "\btest\b", REG_EXTENDED | REG_ICASE)) {
printf("compilation failed\n");
}
regmatch_t match[1];
if (regexec(®ex, hay, 1, match, 0) == REG_NOMATCH) {
printf("couldn't match\n");
}
}
Когда я запускаю эту программу, она печатает couldn't match
, но предложение явно содержит слово TEst
. Может ли кто-нибудь указать на проблему?
\b
— символ возврата. Возможно, какая бы библиотека, которую вы используете (PCRE?), требует фактической обратной косой черты и символа b
, так что \\b
?
Даже при правильном экранировании расширенные регулярные выражения posix не имеют утверждений о границах слов.
И пока вы проверяете, не удалось ли regcomp()
, все, что вам нужно сделать, это распечатать сообщение, а затем продолжить работу, как будто оно удалось. Это не обернется хорошо.
Вам нужно использовать библиотеку PCRE, чтобы получить escape-последовательность \b
для границ слов. pcre.org
Есть две проблемы. \b
— символ пробела. Даже если вы исправите это, удвоив обратную косую черту \\b
, regcomp не распознает это как шаблон и будет искать обратную косую черту, за которой следует символ b
.
Чтобы это работало, вам необходимо настроить регулярное выражение в соответствии с возможностями механизма регулярных выражений (см. страницу руководства regex(7)
).
Измените свое регулярное выражение на: "[^[:alnum:]]test[^[:alnum:]]"
, и вы добьетесь большего успеха.
Обновление. Обратите внимание, что это регулярное выражение также вернет граничные символы. Если вам нужно сохранить проверяемое слово, используйте "[^[:alnum:]](test)[^[:alnum:]]"
и соответствующим образом настройте массив match[]
, чтобы получить совпадающие данные.
Обновление 2: Как отметил @barmar, это не будет работать для текста в начале или конце строки. Чтобы справиться с этим, регулярное выражение необходимо изменить на "(^|[^[:alnum:])(test)([^[:alnum:]]|$)"
.
Это не будет соответствовать слову в начале или конце строки.
Кажется, вам нужно написать "\\btest\\b"