parser

Написать ответ на текущее сообщение

 

 
   команды управления поиском

Парсер выдает то, что ему говорит pcre...

Sumo 15.10.2016 11:45 / 15.10.2016 11:57

И говорит правильно.

Если мы хотим сымитировать поведение /g как в Перле то надо делать некое хитрое действие, если pcre_exec вернул нам для такого выражения «пустое совпадение». Пример из кода ПХП:
do {
                /* Execute the regular expression. */
                count = pcre_exec(pce->re, extra, subject, subject_len, start_offset,
                                                  exoptions|g_notempty, offsets, size_offsets);

...
		/* If something has matched */
		if (count > 0) {

...
		} else if (count == PCRE_ERROR_NOMATCH) {
			/* If we previously set PCRE_NOTEMPTY_ATSTART after a null match,
			   this is not necessarily the end. We need to advance
			   the start offset, and continue. Fudge the offset values
			   to achieve this, unless we're already at the end of the string. */
			if (g_notempty != 0 && start_offset < subject_len) {
				int unit_len = calculate_unit_length(pce, subject + start_offset);

				offsets[0] = start_offset;
				offsets[1] = start_offset + unit_len;
			} else
				break;
		} else {
			pcre_handle_exec_error(count TSRMLS_CC);
			break;
		}

                /* If we have matched an empty string, mimic what Perl's /g options does.
                   This turns out to be rather cunning. First we set PCRE_NOTEMPTY_ATSTART and try
                   the match again at the same point. If this fails (picked up above) we
                   advance to the next character. */
                g_notempty = (offsets[1] == offsets[0])? PCRE_NOTEMPTY_ATSTART | PCRE_ANCHORED : 0;

                /* Advance to the position right after the last full match */
                start_offset = offsets[1];
        } while (global);
Тут лучше подождать moko — пусть он решит надо ли это добавить в Парсер. Есть подозрение, что это может поломать совместимость со старым кодом. :)