2017-02-08 5 views
1

У меня есть список, как это:Замена определенной части

DEL075MD BWP30P140LVT
AN2D BWP30P140LVT
INVD 0P7 BWP40P140
IND2D BWP30P140LVT

Я хочу, чтобы заменить все между D и BWP с *

Как я могу это сделать в unix и tcl

+0

'установить х INVD0P7BWP40P140' ' регулярное_выражение -start 3 Д (.*) BWP $ xabc' 'regsub $ b $ x * d' ' puts $ d' Я сделал это с tcl, я предположил, что мой желаемый 'D' всегда будет после ** 3 ** ** символ **. Но мне нужна универсальная версия This, где позиция 'D' не будет вопросом. Он заменит что-либо между «BWP» и смежным «D» с помощью '*' –

ответ

3
  • У вас есть весь список доступных в то же время, или вы получаете один вещь за раз откуда-то?
  • Должны ли быть обработаны все группы D-BWP или только один элемент?
  • Если только один элемент, должен ли он быть первым или последним (это самые простые альтернативы)?

У Tcl REs нет никакого искателя, что было бы неплохо. Но вы можете обойтись без обоих lookbehinds и lookaheads, если вы захватите стойку ворот и вставьте их в замену как обратные ссылки. Регулярное выражение для текста между стойками ворот должно быть [^DB]+, то есть один или несколько из любого текста, который не включает D или B (чтобы убедиться, что совпадение не выходит за пределы стойки ворот и придерживается других Ds или Bs в тексте). Итак: {(D)[^DB]+(BWP)} (скобки вокруг RE, как правило, хорошая идея).

Если у вас есть весь список и хотите обработать все группы, попробуйте следующее:

set result [regsub -all {(D)[^DB]+(BWP)} $lines {\1*\2}] 

(Если вы можете работать только с одной линией, в то время, это в основном то же самое, вы просто использовать переменную для одной строки вместо переменной для всего списка. В следующих примерах я использую lmap для генерации отдельных строк, что означает, что мне нужно иметь весь список в любом случае, это просто пример.)

Процесс просто первая группа в каждой строке:

set result [lmap line $lines { 
    regsub {(D)[^DB]+(BWP)} $line {\1*\2} 
}] 

процесса только последняя группа в каждой строке:

set result [lmap line $lines { 
    regsub {(D)[^DB]+(BWP[^D]*)$} $line {\1*\2} 
}] 

{(D)[^DB]+(BWP[^D]*)$} RE расширяет правую стойку ворот, чтобы гарантировать, что нет D (и, следовательно, возможно, новая группа) в любом месте между стойкой ворот и концом Струна.

Документация: lmap (for Tcl 8.5), lmap, regsub, set, Syntax of Tcl regular expressions

+0

. Вы даже можете использовать regsub по всему списку: 'set new [regsub -all {(D) [^ DB] + (BWP)} $ the_list {\ 1 * \ 2}}] ' –

+0

@glennjackman: Я просто не знал, как OP хранит свои данные. Я ожидаю уточнения решения. –

+0

@PeterLewerin Спасибо, очень! Это сработало. Я получу один элемент за раз. Я использовал цикл 'foreach' и' regsub {(D) [^ DB] + (BWP)} $ elemet {\ 1 * \ 2} 'сделал все остальное. –

Смежные вопросы