У меня есть строка
static const char *str = ",<ABC$>EEEEEEEE$>,EEE<$WQWERRERR<$ABC>,2233My Name Is $Tom,<ABC$>$>,TTTTTTTEEE<$WQWERRERR<$ABC>,2233My Name Is Jake,<ABC$>$>";
Я хочу получить весь текст между <ABC$>,
заголовком и нижним колонтитулом ,<ABC$>
.
Теперь, если я использую выражение
static const char *regex = "<\\$ABC>,([^>]*),<ABC\\$>";
Обратите внимание, что я использую [^>]
чтобы сделать его неживым.
и распечатать его, используя
struct slre_cap caps[2];
int i, j = 0, str_len = strlen(str);
while (j < str_len &&
(i = slre_match(regex, str + j, str_len - j, caps, 2)) > 0) {
printf("Found Data: [%.*s]\n", caps[0].len, caps[0].ptr);
j += i;
}
Мой вывод выглядит
Found Data: [2233My Name Is $Tom]
Found Data: [2233My Name Is Jake]
Все хорошо до этого момента, но теперь, чтобы добавить шарик кривой, я ввел a >
(который может содержать двоичный протокол сериализации, например, protobuf-embedded-c, который я планирую использовать позже) символ между заголовком и нижним колонтитулом, например <$ABC>,2233My Name Is> $Tom,<ABC$>
. Теперь неожиданно результат изменился. Таким образом, мне было интересно, есть ли способ вместо этого заменить слово ABC
а не единый символ >
для не жадного подхода. Другие библиотеки регулярных выражений делают это с помощью отрицательного lookahead/lookbehind, насколько я знаю, чего нет в SLRE. Можно ли моделировать это поведение в SLRE? Благодарю.
Возможно, регулярные выражения здесь не подходят. Вы можете найти свои подвыражения просто путем поиска фиксированных строк разграничения:
const char *p = str;
for (;;) {
const char *q, *r;
int len;
r = strstr(p, "<$ABC>");
if (r == NULL) break;
r += 6;
q = strstr(r + 6, "<ABC$>");
if (q == NULL) break;
len = q - r;
printf("'%.*s'\n", len, r);
p = q + 6;
}
Изменить: Как указано в комментариях, захваченная строка между разделителями должна, конечно, начинаться после начала разделителя, но strstr
находит свое начало. Следовательно, длина разделительной строки, здесь 6, должна быть добавлена к r
.
Точно так же, если захваченная строка должна включать разделители, r
остается, как и после поиска strstr
и длина разделителя конца должна быть добавлена к q
:
r = strstr(p, "<$ABC>");
if (r == NULL) break;
q = strstr(r + 6, "<ABC$>");
if (q == NULL) break;
q += 6;
len = q - r;
printf("'%.*s'\n", len, r);
p = q;
Замените ваш ([^>]*)
на (.*?)
. точка (.
) означает любой символ. Если ваш код [^>]
означает любой символ, отличный от a >
.
len = q - r-6;
иprintf("'%.*s'\n", len, r+6);