LINUX.ORG.RU

QRegExp разбить строку на части

 


0

2

Всем и всего!

Поскольку слаб в регулярках, помогите, пожалуйста разобрать строки такого вида:

sig_map: bit_vector(27 downto 0):=x"0211111";
input_freq: real := 200.0;--comment text
dll_lock: integer:=dll_lock_time(sim_mode)--comment text

Как выделить одной регуляркой три части строки:

  • имя переменной - от начала строки и до первого символа ":"
  • значение - после символа «=» и до
    • символа ";"
    • конца строки, если нет комментария
    • комментария, начинающегося с "--"
  • комментарий

Можно и по частям, если я слишком много хочу.

★★

Последнее исправление: braboar (всего исправлений: 1)

Принципиально использование QRegExp? Почему не новый QRegularExpression?

Я не понял, что ты хочешь получить в результате и как извлекать данные. Покажи пример, что ты хочешь получить.

А пока, чтобы не терять времени, вот три отдельных Perl-совместимых (PCRE) регекспа для каждого случая. После твоего ответа можно будет уже доработать, склеить в один, доработать для QRegExp. Посмотрим.

  1. ^.*?(?=:)
    $ grep -Po "^.*?(?=:)" /tmp/sample.txt 
    sig_map
    input_freq
    dll_lock
    
  2. (?<=\=).*?(?=(;|$|--))
    $ grep -Po "(?<=\=).*?(?=(;|$|--))" /tmp/sample.txt
    x"0211111"
     200.0
    dll_lock_time(sim_mode)
    
  3. (?<=--).*
    grep -Po "(?<=--).*" /tmp/sample.txt 
    comment text
    comment text
Pravorskyi ★★★
()
Ответ на: комментарий от Pravorskyi

1. У меня не везде есть QRegularExpressions, поэтому для переносимости QRegExp.

2. Каждую из трех строк надо разобрать по частям. До двоеточия - имя переменной, после «=» и до [конец строки|;|--] - её значение, комментарий (все, что после "--").

У меня получается выделить имя переменной и комментарий. А вот получить значение - не выходит.

braboar ★★
() автор топика
Ответ на: комментарий от braboar

У меня не получается сделать это одной регуляркой для QRegExp, основной преградой служит отсутствие возможности установки жадных/ленивых/ревнивых квантификаторов для отдельных групп, и установка флага QRegExp::setMinimal() всё равно приводит к неинтуитивному поведению разных участков регекспа.

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

QRegExp rx("(^.*):.+=([^;]+(?=;|--|));?(?:--(.*))?$");
rx.setPatternSyntax(QRegExp::RegExp2);
rx.setMinimal(true);

Проблема с последней тестовой строкой.

https://regex101.com/r/NYci3A/1 можно увидеть, как отличается поведение эталонных (ну, почти) регекспов от QRegExp.

В качестве временного workaround могу предложить разбирать строку на части с помощью поиска разделителей и простой арифметики:

// Name
int n = str.indexOf(':');
QString name = str.mid(0, n);

// Comment
const QString cmDelimiter("--");
int startVal = str.indexOf('=', n) + 1;
int startCm  = str.indexOf(cmDelimiter, startVal);
QString comment = startCm == -1 ? QString() : str.mid(startCm + cmDelimiter.length());

//Value
n = startCm == -1 ? str.length() - startVal : startCm - startVal;
int semicolon = str.indexOf(';');
n = semicolon == -1 ? n : semicolon - startVal;
QString value = str.mid(startVal, n);

qDebug() << name << value << comment;

Завтра можно подумать над решением с тремя регекспами, если будет ещё актуально. Хотя для извлечения конкретно name регексп будет излишним, там и так две строчки.

Pravorskyi ★★★
()
(\w+):[^=]*=([^--]+)(--(.*))?

1 - имя переменной, 2 - значение, 4 - коммент.

P.S. В 3 строке у тебя после значения нет ';', это опечатка?

SR_team ★★★★★
()
Последнее исправление: SR_team (всего исправлений: 2)
Ответ на: комментарий от SR_team

Нет, не опечатка. В исходном файле строки в секции разделяются ";", в последней строке - нет.

braboar ★★
() автор топика
Ответ на: комментарий от Pravorskyi

В прототипе на tcl/tk так и было, но в тикле я делал сплит строки, задавая список разделителей, чего нет в QString. Возможно, так и придется сделать, разбивая строку и отрезая ненужное.

braboar ★★
() автор топика
Ответ на: комментарий от braboar

В QString вроде можно задавать список разделителей через тот самый QRegExp. Как-то так:

str.split(QRegExp("aaa|bbb|ccc"));

И в indexOf() тоже можно указать такой примитивный QRegExp.

Pravorskyi ★★★
()
Ответ на: комментарий от Pravorskyi

В принципе, да, но мне кажется ваше предыдущее предложение

разбирать строку на части с помощью поиска разделителей и простой арифметики

вполне приемлемым.

braboar ★★
() автор топика
Последнее исправление: braboar (всего исправлений: 1)

Всем спасибо за внимание и помощь!

braboar ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.