Пример регулярного выражения TCL - PullRequest
1 голос
/ 01 июля 2011

Я хочу получить слово в строке, которая начинается с abc_ или с xyz_, написав регулярное выражение.Вот мой сценарий:

[regexp -nocase -- {.*\s+(abc_|xyz_\S+)\s+.*} $str all necessaryStr]

Так что, если я применю приведенное выше регулярное выражение к str1 и str2, я хочу получить "xyz_hello" из $ str1 и "abc_bye" из $ str2.

set str1 "gfrdgasjklh dlasd =-0-489 xyz_hello sddf 89rn sf n9"
set str2 "dytfasjklh abc_bye dlasd =-0tyj-489 sddf tyj89rn sjf n9"

Но мои регулярные выражения не работают.И мои вопросы:

1) Что не так с моим регулярным выражением?2) Хорошо ли найти произведения, начинающиеся с некоторых предопределенных префиксов с помощью регулярного выражения, или лучше использовать строковые функции (совпадение строк или около того)?

Ответы [ 3 ]

2 голосов
/ 01 июля 2011

Непонятно в вашем вопросе, из чего состоит слово.Допускаются ли дополнительные подчеркивания?Разрешены ли цифры?Как насчет «слов, которые состоят только из префикса», например, «abc_» или «xyz»?

Делая консервативные предположения (основанные на ваших примерах), что вы ожидаете только буквы от английского алфавита, по крайней мерееще один символ, и вы не заботитесь о регистре, вы можете упростить свое регулярное выражение:

[regexp -nocase -- {\m(abc_|xyz_)[a-zA-Z]+} $str match]

Это установит match в соответствующее слово.Вы можете заменить квадратные скобки, если ваше определение слова отличается от моих предположений.

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

Некоторые вопросы, которые следует учитывать:

  • Действительно ли производительность имеет значение?Если вы не выполняете поиск в узком цикле или ищете очень длинные строки, я подозреваю, что разница в производительности не будет существенной.Подождите, пока у вас не возникнет проблема с производительностью, затем профилируйте свое приложение, чтобы увидеть узкое место, затем вы можете протестировать альтернативные реализации.
  • Удобство будет зависеть от предпочтений программиста (ов), которые должны писатьи поддерживать код.Любят ли они / ненавидят использование регулярных выражений?
  • Использование регулярных выражений может предложить большую гибкость, но это может быть за счет читабельности.

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

2 голосов
/ 01 июля 2011

На основании того, что вы написали, вы, похоже, представляете собой слова, начинающиеся с abc_ или xyz_ (в любом случае) и имеющие только буквы после этого.Хорошая первая попытка сопоставления это:

regexp -nocase -- {\y(?:abc_|xyz_)[a-z]+} $str match

Особенности этого:

  • \y означает, что это соответствует только в начале слова (теоретически конец слова тоже, но мы следуем за ним буквой во всех случаях!)
  • (?:…) группирует без захвата
  • Жадное сопоставление означает, что мы получим все слово (если оно просто означает буквыASCII диапазон UNICODE).Попробуйте использовать \w или \S вместо [a-z], но они изменяют семантику сопоставляемого (\w даст вам представление о том, какие символы обычно разрешены в идентификаторах программы, а \S даст вампробелы).
0 голосов
/ 01 июля 2011

Я исправил это: [regexp -nocase - {. * \ S + ((abc_ | xyz _) \ S +) \ s +. *} $ Str все необходимоеStr]

Но все же хотел бы знатьесли регулярное выражение является лучшим решением или функция строки лучше (быстрее, удобнее, гибче).

...