Дополнительный групповой захват с сопоставлением шаблонов Lua

Я пытаюсь разобрать химические формулы в Lua, используя простое сопоставление с образцом. Однако я не знаю, как указать группу захвата как необязательную. Вот шаблон, который я придумал:

pattern = "(%u%l*)(%d*)"

Первая группа фиксирует символ атома (например, «H», «He» и т. д.), а вторая группа фиксирует номер этого атома в молекуле. Это значение обычно является целым числом, но если оно равно 1, оно часто опускается, например:

formula = "C2H6O"

Когда я пытаюсь выполнить глобальное совпадение, если совпадения нет, результатом count будет '' вместо того, что я ожидал от nil.

compound = {}
for atom,count in string.gmatch(formula, pattern) do
    compound[atom] = count or 1
end

Очевидно, я мог бы просто проверить, count = ''но мне было любопытно, есть ли в Lua необязательная группа захвата.


person Moop    schedule 25.09.2014    source источник


Ответы (2)


если бы в Lua была необязательная группа захвата.

Нет; элементы шаблона не указывают захваты в качестве допустимых вариантов, поэтому не может иметь, например, (%d*)?, как в Perl.

person Paul Kulchenko    schedule 25.09.2014
comment
Спасибо, отличная работа над ZeroBrane BTW, это то, что я сейчас использую :) - person Moop; 25.09.2014
comment
Спасибо Муоп за отзыв! - person Paul Kulchenko; 25.09.2014

В Lua нет дополнительной группы захвата.

count — это пустая строка вместо nil, потому что пустая строка соответствует %d*.

Попробуйте это вместо этого:

compound[atom] = tonumber(count) or 1

Обратите внимание, что tonumber вернет nil, если count является пустой строкой, что вы и хотите проверить.

person lhf    schedule 25.09.2014
comment
Я не понимаю, что вы имеете в виду, когда это соответствует пустой строке. Не могли бы вы объяснить больше об этом? Разве ничто не будет соответствовать всему? - person Moop; 25.09.2014
comment
@Moop, %d* означает ноль или более цифр. - person lhf; 25.09.2014
comment
@ihf Конечно, но разве это не означает, что он соответствует каждой пустой строке? - person Moop; 25.09.2014
comment
@Moop, %d* соответствует пустой строке, но не обязательно на ней заканчивается; на самом деле он соответствует самой длинной возможной строке цифр или ни одной, если ее нет. - person lhf; 25.09.2014