Вы используете якоря ^
и $
в однострочном режиме, поэтому ^
соответствует началу строки, а $
соответствует концу строки, а не привязывается к строкам.
C++ regex
библиотека не имеет возможности многострочный/однострочные, что .NET имеют Регулярные выражения, так что вы хотите использовать regex_search
вместо regex_match
, но, как я сказал в моем замечании-ответ на Ваше оригинальное сообщение : вы не должны использовать регулярные выражения для анализа ассемблерного кода, а при использовании регулярного выражения в качестве грубого инструмента для токенирования используется свайный драйвер, когда вам нужен только молоток: strtok
- ваш друг.
char* input = "MOV R\nADD R\nSUB 30\nSTORE 1000\nHALT";
const char* delimiters = " \n"
char* token = strtok(input, delimiters );
while(token != nullptr) {
cout << token << endl;
token = strtok(nullptr, delimiters);
}
Обратите внимание, что strtok
является состоянием, что объясняет недетерминированный характер последующих вызовов к strtok
с nullptr
в качестве первого аргумента. Это описано здесь: http://www.cplusplus.com/reference/cstring/strtok/
отметить также, что strtok
фактически изменяет входной строки, следовательно, почему input
является char*
, а не const char* const
или string
(потому что string::c_str()
возвращает const char*
).
strtok
является, к сожалению, одной из функций C, которая, к сожалению, не имеет C++ - идиоматической альтернативы. Вы можете использовать метод Boost string::split
, но это вводит новое распределение памяти, тогда как strtok
изменяет буфер строки на месте, чтобы преобразовать разделители в \0
, чтобы вы могли использовать значения char*
с нулевыми функциями строки - поэтому у него есть свои преимущества (то есть без дополнительных необходимо выделить память или дополнительное строковое копирование).
Более полное решение:
Проблема strtok
в том, что вы не знаете, какой разделитель был просто перезаписывается, поэтому если у вас есть грамматика, придающую различные разделители различных семантических (как в вашем случае : '
' (пробел) является операндом-разделителем, а `` \ n 'является разделителем кода операции.
Решение состоит в том, чтобы иметь копию строки, которая не была изменена, и использовать относительные указатели для получить индекс символа, чтобы определить, какой разделитель был встречен. Это несколько поражает точку usi нг strtok
, чтобы свести к минимуму использования памяти, хотя, но это не избавляет от необходимости проверять каждое возвращаемое значение как средство обеспечения соблюдения ваших правил грамматики:
const char input[] = "MOV R\nADD R\nSUB 30\nSTORE 1000\nHALT";
char* temp = calloc(sizeof(input), sizeof(char));
strcpy(temp, input);
const char* delimiters = " \n"
char* token = strtok(temp, delimiters );
while(token != nullptr) {
char delimiter = input[ token - temp ];
cout << token << endl;
switch(delimiter) {
case ' ':
cout << token << " ";
break;
case '\n':
cout << endl << token << " ";
break;
}
token = strtok(nullptr, delimiters);
}
Пожалуйста, не используйте регулярные выражения для разбора кода сборки. Сборочный код не является примером обычного языка и поэтому не может быть правильно проанализирован регулярным выражением. – Dai
Хотя вы используете регулярное выражение как средство разделения строки (и если вы используете C/C++, просто используйте 'strtok'), это плохая идея с точки зрения потребления памяти. Вместо этого используйте простой парсер с конечным автоматом (и он также будет поддерживать потребление памяти). – Dai
Но онлайн-тестер смог правильно разобрать его. – MrWarlock616