Что такое выражение регулярного выражения C ++? [Дубликат]

В Firefox любая недопустимая дата возвращается как объект Date как Date 1899-11-29T19:00:00.000Z, поэтому проверьте, является ли браузер Firefox, а затем получает объект Date строки "1899-11-29T19:00:00.000Z".getDate(). Наконец сравните его с датой.

8
задан Piotr Skotnicki 24 September 2015 в 15:46
поделиться

3 ответа

Вы получаете 1, потому что regex_search возвращает только 1 совпадение, а size() возвращает количество групп захвата + все значение соответствия.

Ваш matches is ...:

Объект типа match_results (например, cmatch или smatch), который заполняется этой функцией, с информацией о результатах совпадения и любой найдены подматрицы.

Если [поиск по регулярному выражению] успешный, он не пуст и содержит ряд объектов sub_match: первый элемент sub_match соответствует всему совпадению, если выражение регулярного выражения содержало подвыражения, которые должны быть сопоставлены (т. е. группы с разделителями в скобках), их соответствующие подрежимы сохраняются как последовательные элементы sub_match в объекте match_results.

код, который найдет несколько совпадений:

#include <string>
#include <iostream>
#include <regex>
using namespace std;
int main() {
  string str("abcdefabcghiabc");
  int i = 0;
  regex rgx1("abc");
  smatch smtch;
  while (regex_search(str, smtch, rgx1)) {
        std::cout << i << ": " << smtch[0] << std::endl;
        i += 1;
        str = smtch.suffix().str();
  }
  return 0;
}

См. IDEONE demo , возвращающий abc 3 раза.

Поскольку этот метод уничтожает входную строку, здесь другая альтернатива, основанная на std::sregex_iterator (std::wsregex_iterator, должна использоваться, когда y наш объект является объектом std::wstring):

int main() {
    std::regex r("ab(c)");
    std::string s = "abcdefabcghiabc";
    for(std::sregex_iterator i = std::sregex_iterator(s.begin(), s.end(), r);
                             i != std::sregex_iterator();
                             ++i)
    {
        std::smatch m = *i;
        std::cout << "Match value: " << m.str() << " at Position " << m.position() << '\n';
        std::cout << "    Capture: " << m[1].str() << " at Position " << m.position(1) << '\n';
    }
    return 0;
}

См. демонстрацию IDEONE , возвращая

Match value: abc at Position 0
    Capture: c at Position 2
Match value: abc at Position 6
    Capture: c at Position 8
Match value: abc at Position 12
    Capture: c at Position 14
9
ответ дан Wiktor Stribiżew 24 August 2018 в 15:45
поделиться
Решение

@ stribizhev имеет квадратичную сложность худшего случая для правильных регулярных выражений. Для безумных (например, «y *») он не заканчивается. В некоторых приложениях эти проблемы могут быть вызваны DoS-атаками . Вот фиксированная версия:

string str("abcdefabcghiabc");
int i = 0;
regex rgx1("abc");
smatch smtch;
auto beg = str.cbegin();
while (regex_search(beg, str.cend(), smtch, rgx1)) {
    std::cout << i << ": " << smtch[0] << std::endl;
    i += 1;
    if ( smtch.length(0) > 0 )
        std::advance(beg, smtch.length(0));
    else if ( beg != str.cend() )
        ++beg;
    else
        break;
}

Согласно моим личным предпочтениям, это найдет n + 1 совпадений пустого регулярного выражения в строке длины n. Вы также можете просто выйти из цикла после пустого совпадения.

Если вы хотите сравнить производительность для строки с миллионами совпадений, добавьте следующие строки после определения str (и не забудьте включить оптимизацию), один раз для каждой версии:

for (int j = 0; j < 20; ++j)
    str = str + str;
0
ответ дан Arne Vogel 24 August 2018 в 15:45
поделиться

Что вам не хватает, так это то, что matches заполняется одной записью для каждой группы захвата (включая всю согласованную подстроку как 0-й захват).

Если вы пишете

std::regex needle("a(b)c");
]

, то вы получите matches.size()==2, с matches[0]=="abc" и matches[1]=="b".

3
ответ дан Toby Speight 24 August 2018 в 15:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: