2010-07-20 3 views
2

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

[2010-01-15 06: 18: 10,203] [0x00001388] [SHDNT] Shutdown Count Down = 2/5

[2010-01-15 06: 18: 11.203] [0x00001388] [SHDNT] Выключить счетчик вниз = 3/5

И я хочу, чтобы иметь возможность захватить в моем поиске '[' и ']' вокруг даты. Я подумал о том, чтобы найти «[», используя некоторые критерии, такие как («[», а затем [0-9] [0-9] означает две цифры) и «]» с (']' продолжение '. [0-9] [0-9] [0-9] 'означает точку и 3digits).

Я пробовал это, но он дает ошибку \ [(? = [0-9] [0-9]) для первого поиска. Разве это не позволяет мне ставить? сразу после скобки.

Как я должен выполнить поиск?

Заранее спасибо

EDITED ДОБАВИТЬ

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

+1

На каком языке вы работаете? Могут быть другие решения, не использующие RegEx. –

+0

@ p.campbell Я использую его с обычным текстовым редактором с функциями поиска и замены, поддерживающим поиск по шаблону. Не язык программирования. – Precious

+1

Хорошо, какой * редактор * вы используете? Во всяком случае, вы должны просто соответствовать всему, захватить дату и подключить ее обратно, как это сделал @sarnold. –

ответ

2

Следующее регулярное выражение:

^\[([^\]]+)\] 

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

Обратите внимание, что ваш текстовый редактор может иметь несколько иной синтаксис. Вот как это ломается:

^ = beginning of line/string 
\[, \] = literal [ and ] characters 
() = signifies a group to capture 
[^\]] = matches any character _except_ a close bracket 
     (this keeps the match from being too greedy) 
+ = one or more of the previous 

EDIT: это предполагает, что регулярное выражение объект поддерживает группы (который большинство из них). Самый простой способ объяснить группы - просто показать вам, как они работают с одним из таких движков.В интерпретаторе:

>>> import re 
>>> s = '[2010-01-15 06:18:10.203] [0x00001388] [SHDNT] ...' 
>>> r = re.compile(r'^\[([^\]]+)\]') 
>>> m = r.search(s) 

Это создает объект регулярного выражения и поиск в строке для первого набора текста, который соответствует его. Результат возвращается в объект матча:

>>> m 
<_sre.SRE_Match object at 0x1004d9558> 

Чтобы получить весь набор текста, было помечено, конвенция Питон для вызова group() на объекте матча:

>>> m.group() 
'[2010-01-15 06:18:10.203]' 

и к получите только что-нибудь в круглых скобках, я передаю номер группы, которую я хочу (в этом случае есть только один набор парнеров, поэтому только одна группа):

>>> m.group(1) 
'2010-01-15 06:18:10.203' 

Если я выполняю замену вместо поиска, я использую функцию sub. Sub принимает строку, я хочу, чтобы заменить полный матч за счет, а затем входной строки и возвращает строку с заменой выполняется, если совпадение найдено:

>>> r.sub('spam spam spam', s) 
'spam spam spam [0x00001388] [SHDNT] ...' 

Однако замена строки поддерживает управляющие последовательности которые относятся к конкретным значениям групп, захваченных совпадением. Групповое замещение обозначается \N, где N - номер группы. Следовательно:

>>> r.sub(r' \1 ', s) 
' 2010-01-15 06:18:10.203 [0x00001388] [SHDNT] ...' 

Это то, что вы хотите.

+0

Хорошо, отлично. он фиксирует всю дату. Итак, как я могу включить только [и] в результат, задав только критерии даты. в этом примере q (? = u) предположим, что мы получаем результат «q», убедившись, что за ним следует «u», но не добавляя «u» к результату. Как я могу добиться этого, потому что я хочу заменить [и] пустым пространством в конце. – Precious

+1

Ну, это будет соответствовать всем, включая квадратные скобки, но извлеките часть в круглых скобках в группу, которую вы можете вставить в заменяющую строку. Итак, предполагая, что ваш регулярный редактор вашего текстового редактора обрабатывает такие замены, вы можете записать в качестве замены что-то вроде «\ 1» (с пробелами по обе стороны от \ 1), чтобы заменить весь матч (включая скобки) с датой в группа 1 и пространство с обеих сторон. –

+0

Спасибо большое за ваше время. Мне нравится идея его точно, что я пытаюсь выполнить, но можете ли вы объяснить мне, как я это делаю? «Извлеките часть в круглых скобках в группу, которую вы можете вставить в заменяющую строку» ??? – Precious

1

Я не уверен, что вам нужно использовать предпросмотр или утверждения в 'назад ваше регулярное выражение:

[email protected]:/tmp$ cat date.pl 
#!/usr/bin/perl -w 

while(<>) { 
    /^(\[\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d\.\d\d\d\])/; 
    print "$1\n"; 
} 
[email protected]:/tmp$ cat data 
[2010-01-15 06:18:10.203] [0x00001388] [SHDNT] Shutdown Count Down = 2/5 
[2010-01-15 06:18:11.203] [0x00001388] [SHDNT] Shutdown Count Down = 3/5 
[email protected]:/tmp$ ./date.pl data 
[2010-01-15 06:18:10.203] 
[2010-01-15 06:18:11.203] 

Я не мог сказать из вашего описания, если вы сделать хотите [ и ] вокруг даты , или если вы не хотите их. Если вы не хотите, квадратные скобки, переместить их вне скобок:

 /^\[(\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d\.\d\d\d)\]/; 

[email protected]:/tmp$ ./date.pl data 
2010-01-15 06:18:10.203 
2010-01-15 06:18:11.203 

Обратите внимание, что я также якорь регулярное выражение в начале строки, в случае выхода включает в себя дату, время вещь в скобки где-то еще. Кроме того, я превысил дату-время по сравнению с вашим примером. Считайте это паранойей. Если вы хотите заменить \d\d\d\d на \d{4}, вы можете, но в этом примере я нахожу более длинную форму более читаемой.

+0

Спасибо, но все, что я пытаюсь сделать, это удалить скобки вокруг даты для нескольких файлов одновременно. Пока остальная часть данных остается прежней. Я не хочу кодировать. Лишь простая линия регулярных выражений. – Precious

2

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

$ cat file 
[2010-01-15 06:18:10.203] [0x00001388] [SHDNT] Shutdown Count Down = 2/5 
[2010-01-15 06:18:11.203] [0x00001388] [SHDNT] Shutdown Count Down = 3/5 

$ awk -F"]" '{print $1"]"}' file 
[2010-01-15 06:18:10.203] 
[2010-01-15 06:18:11.203] 

или просто распечатать поля 1 и 2, используя пробелы в качестве разделителей

$ awk '{print $1,$2}' file 
[2010-01-15 06:18:10.203] 
[2010-01-15 06:18:11.203] 

Update: Для того, чтобы снять квадратные скобки, просто используйте gsub() или sub() на полях 1 и 2

$ awk '{gsub(/^\[/,"",$1);gsub(/\]$/,"",$2)}1' file 
2010-01-15 06:18:10.203 [0x00001388] [SHDNT] Shutdown Count Down = 2/5 
2010-01-15 06:18:11.203 [0x00001388] [SHDNT] Shutdown Count Down = 3/5 
0

Я согласен с ghostdog, что вы должны держать его простым, но вы можете сохранить его простым и с регулярными выражениями:

  1. ^ соответствует началу строки.
  2. . соответствует любому символу.
  3. *? соответствует предыдущей вещи, ноль или более раз НЕ-GREEDILY, что означает, что не требуется больше, чем нужно, чтобы сделать остальное регулярное выражение.

Поместите это вместе, и вы получите ^.*?\], совпадающий с начала строки до первого ], что она видит.

РЕДАКТИРОВАТЬ: Просто увидел ваш ответ на ghostdog, который прояснил проблему. Еще легче сопоставить всю дату с фигурными скобками. После этого просто замените всю строку на себя, минус первый и последний символ. Я не знаю, какой язык вы используете, но в Python, было бы что-то вроде этого:

new_string = re.sub(r'^.*?\]',original_string,lambda m:m.group()[1:-1]) 
+0

Спасибо. Но этот поиск будет отображать весь поиск. Вот что я сделал, что позволило мне выделить [в начале даты, но добавляет цифру к ней.^\\ [(.? [0-9]) То, что я хочу сделать, это выделить только «[», делая только цифры, но не обязательно включаться в результат. Есть ли смысл? потому что посмотрите вокруг q (? = u) печатает «q» (за которым следует «u»), он пропускает «u» из результата. – Precious

+0

Это хорошо, но я действительно не использую какой-либо язык программирования просто простой текстовый редактор с функцией поиска и замены. – Precious

0

Поскольку ваш входной формат настолько жесткий взять очень простой способ:

$ cut -c 2-24 <<EOF 
[2010-01-15 06:18:10.203] [0x00001388] [SHDNT] Shutdown Count Down = 2/5 
[2010-01-15 06:18:11.203] [0x00001388] [SHDNT] Shutdown Count Down = 3/5 
EOF 

2010-01-15 06:18:10.203 
2010-01-15 06:18:11.203 
0

Не абсолютно уверен, что вам нужно регулярное выражение здесь. Если это вопрос поиска первого символа или определения текста в квадратных скобках. Возможно, я неправильно понял ваш вопрос?

C# пример:

LINQ:

string[] firsts = myFile.ReadAllLines().Select(f=>f[0]); 

Looping с foreach:

string[] allLines = myFile.ReadAllLines(); 
foreach (string line in allLines) 
{ 
    char firstChar= line[0]; 
    Console.WriteLine("First char: " + firstChar.ToString()); 

    if (firstChar = '[') 
    { 
     int closing = line.IndexOf(']'); 
     string textWithin = line.SubString(0, closingSquare-1); 
     Console.WriteLine("Found this text within the square brackets: " + textWithin); 
    } 
} 
0

Ах, спасибо за ваш дополнительный комментарий в одном из ответов.

В Vim, я бы, вероятно, использовать визуальный инструмент выбора: поместить курсор на первый [, тип ^V, G (чтобы добраться до конца файла), а затем x удалить столбец. Затем повторите с первого ] характера, ^V, G (но G поместит курсор на неправильный символ - так используйте l или стрелка вправо-ключ, чтобы переместиться в ]), а затем введите x, чтобы удалить столбец.

Если не выстраиваются в линию совершенно в столбцах (возможно, .203 может быть меньше символов, скажем .2), то я хотел бы сделать это:

:%s/^\[// 
:%s/\(\d\)] /\1/

отмечая, конечно, что второе регулярное выражение гораздо более хрупким ; он удалит первый ], который находится между цифрой и пробелом в каждой строке. Non-vim не будет так раздражать насчет побега ( и ).

Конечно, если вы не используете vi-clone, мы надеемся, что это может перевести достаточно хорошо. :)

+0

Спасибо, но я не использую Vim. – Precious

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