запретить вложенным группам портить совпадения регулярных выражений (TCL)

#regex #tcl

#регулярное выражение #tcl

Вопрос:

У меня есть файл с несколькими разделенными пробелами числами с плавающей точкой. Количество значений с плавающей точкой может варьироваться. Ради аргумента предположим, что это 5. Я взял регулярное выражение с этой страницы руководства :

www.regular-expressions.info/floatingpoint.html

 [- ]?[0-9]*.?[0-9] ([eE][- ]?[0-9] )?
  

Чтобы перехватить несколько значений с плавающей точкой, я вставил это в группу, добавил несколько пробелов и снова сгруппировал с помощью? квантификатор.

 (([- ]?[0-9]*.?[0-9] ([eE][- ]?[0-9] )?)s ) 
  

Я понимаю, что это создало вложенные группы, и на этом мои знания заканчиваются. Когда я тестирую регулярное выражение, я получаю нежелательные совпадения «подгрупп», то есть показателей.

Итак, мой вопрос: как мне захватить только группы «первого уровня», которые являются моими полными значениями с плавающей точкой?

Образец набора тестовых данных (обратите внимание на различное количество пробелов):

 set x "  1.0034e-09 -0.34e 07    -3 0.46   3.445e 03   "
  

Спасибо,
Герт

Ответ №1:

Тот факт, что ваше выражение содержит вложенные группы захвата, не означает, что вы сможете получить доступ к этим повторяющимся захватам, доступным будет только текст, захваченный во время последней итерации.

Кроме того, каждая группа захвата возвращается в Tcl, и если вам это не нужно, преобразуйте все группы захвата в не-захватывающие ( ([eE][- ]?[0-9] )?) => (?:[eE][- ]?[0-9] )? ).

Чтобы сопоставить все числа в вашем тестовом наборе, вы можете использовать

 set x {  1.0034e-09 -0.34e 07    -3 0.46   3.445e 03   }
set RE {[- ]?[0-9]*.?[0-9] (?:[eE][- ]?[0-9] )?}
set res [regexp -all -inline $RE $x]
puts $res
  

Смотрите демонстрационную версию IDEONE

ОБРАТИТЕ внимание, что [- ]?[0-9]*.?[0-9] (?:[eE][- ]?[0-9] )? регулярное выражение соответствует целочисленным или плавающим значениям. Чтобы сопоставлять только значения с плавающей точкой, используйте [- ]?[0-9]*.[0-9] (?:[eE][- ]?[0-9] )? (после удалите необязательный квантификатор — один или ноль вхождений ? . ).