LINUX.ORG.RU

Регулярные выражения для поиска


0

1

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

★★

Что-то типа такого (т.е. последовательно отфильтровываем то что нам не надо):

Допустим, @ и # - это такие символы.

$ cat test
asd fasljal @asdfa;sdflj# asdf
1asd@
2#adfkljl
asdfasf
3adsf##adfadsf@

$ cat test | sed -e '/^[^@]*@[^@]*[^#]*#[^#@]*$/d'| sed -e '/^[^#]*#[^#]*[^@#]*@[^@]*$/d'| sed -e '/^[^#@]*$/d'
1asd@
2#adfkljl
3adsf##adfadsf@

siberean ()
Ответ на: комментарий от anTaRes

Я не могу использовать потоковые редакторы или внешние скрипты-обработчики - нет прав, так что я вынужден оставаться в рамках того редактора, в котором был открыт файл. Моё счастье, что он вообще поддерживает поиск по РВ.

zzdnx ★★ ()
Ответ на: комментарий от siberean

последовательно отфильтровываем то что нам не надо

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

zzdnx ★★ ()
Ответ на: комментарий от belous_k_a

Но это зависит от редактора, в общем случае надо указать начало и конец строки, да еще и можно объединить оба запроса:

//f - first char
//s - second char

^([^f]*s[^f]*|[^s]*f[^s]*)$
belous_k_a ()
Ответ на: комментарий от belous_k_a

А строка с дублированными символами, вроде «fss»?
Тогда уж так:
^([^f]*s[^f]*|[^s]*f[^s]*)$|f.*f|s.*s

(если я правильно понял последнее предложение)

proud_anon ★★★★★ ()
Ответ на: комментарий от zzdnx

Очень жёсткие требования. Те, кто от вас хочет подобных задач - должен дать такое право, иначе задачу решить может быть невозможно. А sed - это база, почти как grep. Чем сидеть дни с поиском возможно несуществующего решения - более оптимально дать за секунду права и получить решение за 5 минут. Если винда - поставьте цигвин и запустите команду, подобную той, что я дал выше. Она по крайней мере работает (хотя нуждается в тестинге с большим количеством сочетаний).

siberean ()
Ответ на: комментарий от proud_anon

Вообще, приведёная идея мне понравилась: создать списоктакого вида - исключить появление №1 до появления №2, после чего снова исключить №1, а потом то же, но поменять местами №2 и №1. - этот запрос выполняет сразу половину дела, но совместно не работает. Самое противное, что даже такая конструкция как .*[^1].*2.*[^1].* находит мне строки, которые содержат ОБА символа. Аналогично ведёт себя и конструкция .*1.*[^2].*, хотя я чётко ввожу аллергию на символ №2.

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

zzdnx ★★ ()
Ответ на: комментарий от zzdnx

этот запрос выполняет сразу половину дела, но совместно не работает

Это почему? В том редакторе не допускается знак «|» в регулярных выражениях?

Самое противное, что даже такая конструкция как .*[^1].*2.*[^1].* находит мне строки, которые содержат ОБА символа. Аналогично ведёт себя и конструкция .*1.*[^2].*, хотя я чётко ввожу аллергию на символ №2.

Конечно находит. Смотрите:

1abc2abcd
против: .*[^1].*2.*[^1].*
.* = «1ab»
[^1] = «c»
2 = «2»
.* = «abc»
[^1] = «d»
.* = ничего

против: .*1.*[^2].*
.* = ничего
1 = «1»
.* = «abc2abc»
[^1] = «d»
.* = ничего


[^1] - это не «аллергия на [^1]», это «любой символ кроме 1» . Единственная возможная в регулярных выражениях «аллергия» - это negative lookaround. Впрочем, если у вас даже альтернация не поддерживается, то lookaround тем более.

proud_anon ★★★★★ ()
Ответ на: комментарий от proud_anon

альтернация поддерживатся

Я могу искать SS и SP отдав запрос \sS[S|P]\s, так что символ альтернации поддерживается, но у меня СЛИШКОМ мало опыта в использовании регулярных выражений.

zzdnx ★★ ()
Ответ на: комментарий от zzdnx

штук 7 выражений

Я тред не читал, но неужели выше не дали правильного решения?

$ echo -e 'zzzBA\nzAzAzA\nzBzBzBzB\nA\nB\nBzBB\nAzAA\nzzzzAzzzB' | egrep '^(([^B]*(A[^B]*)+)|([^A]*(B[^A]*)+))$'
zAzAzA
zBzBzBzB
A
B
BzBB
AzAA
geekless ★★ ()
Ответ на: комментарий от geekless

тред не читал

А жаль. Читать надо до того, как советуете, хотя за вариант - спасибо.

zzdnx ★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.