2015-02-20 2 views
2

У меня есть этот тип текста:Почему это рабочее регулярное выражение не работает с sed?

Song of Solomon 1:1: The song of songs, which is Solomon’s. 
John 3:16:For God so loved the world, that he gave his only begotten Son, that whosoever believeth in him should not perish, but have everlasting life. 
III John 1:8: We therefore ought to receive such, that we might be fellowhelpers to the truth. 

Я пытаюсь удалить стих (или метаданные, если вы будете) и просто получить простой текст содержания. В тексте примера показаны три разных типа стихов (многословное, однослоговое и римское + слово), я думал, что с начала каждой строки будет легче обнаружить , что угодно до тех пор, пока «число: число:», а затем замените его с "" (пустая строка).

Я проверил регулярное выражение, которое, кажется, работает (как я описал):

  1. Сначала не найти, пока ": Номер:" за исключением его [или:.? + (= (\ S +) (\ d +) (:) (\ d +) (:))],
  2. Затем укажите шаблон «число: число:» [или: (\ s +) (\ d +) (:) (\ d +) (:) ]

Это приводит к следующему регулярному выражению:

.+?(?=(\s+)(\d+)(:)(\d+)(:))(\s+)(\d+)(:)(\d+)(:) 

Регулярное выражение, кажется, работает хорошо, вы можете попробовать его here, проблема в том, что, когда я пытаюсь использовать регулярное выражение с СЭД он просто не работает:

$ sed 's/.+?(?=(\s+)(\d+)(:)(\d+)(:))(\s+)(\d+)(:)(\d+)(:)//g' testcase.txt 

Он будет производить тот же текст в качестве входных данных, когда оно должно произвести:

The song of songs, which is Solomon’s. 
For God so loved the world, that he gave his only begotten Son, that whosoever believeth in him should not perish, but have everlasting life. 
We therefore ought to receive such, that we might be fellowhelpers to the truth. 

Любая помощь пожалуйста?

спасибо!

+0

попытка :: СЕПГ -i «s /. +() = (\ s +) (\ d +) (:) (\ d +) (:))/(\ s +) (\ d +) (:) (\ d +) (:)/g ' –

+0

'\ s' и' \ d' являются и PCRE. Стандартный POSIX sed не знает PCRE. –

+0

(Таким образом, @AlexisPeters, который не будет работать со многими/всеми версиями sed). –

ответ

1

Вы можете использовать следующую sed команду:

sed 's/.*[0-9]\+:[0-9]\+: *//' file.txt 

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

sed 's/.*[0-9]\{1,\}:[0-9]\{1,\}: \{0,\}//' file.txt 

Мне нужно использовать \{1,\}, так как оператор \+ и \* не является частью основной формулы регулярного выражения posix.


Btw, если у вас есть GNU лакомства, вы также можете использовать grep:

grep -oP '.*([0-9]+:){2} *\K.*' file.txt 

Я использую вариант \K здесь. \K очищает текущее совпадение до этой точки, которое может использоваться как утверждение lookbehind, но с переменной длиной.

+0

Большое спасибо @ hek2mgl Я отметил ваш ответ как решение моей проблемы. Я нашел основное rexx posix очень полезным. Большое спасибо! –

+0

Рад видеть, что это помогает. Добро пожаловать – hek2mgl

2

Это awk должны сделать:

awk -F": *" '{print $3}' file 
The song of songs, which is Solomon.s. 
For God so loved the world, that he gave his only begotten Son, that whosoever believeth in him should not perish, but have everlasting life. 
We therefore ought to receive such, that we might be fellowhelpers to the truth. 

Чтобы сделать его более безопасным для number:number: использования этого:

awk -F"[0-9]+:[0-9]+: *" '{print $2}' file 
The song of songs, which is Solomon.s. 
For God so loved the world, that he gave his only begotten Son, that whosoever believeth in him should not perish, but have everlasting life. 
We therefore ought to receive such, that we might be fellowhelpers to the truth. 

Это также поможет избежать проблем с : в тексте.

Используя регулярное выражение Adams, мы можем сократить его.

awk -F"([0-9]+:){2} ?" '{print $2}' file 

или

awk -F"([0-9]+:){2} ?" '{$0=$2}1' file 
+0

Спасибо за ваш ответ @ Jotne, мне понравилось ваше решение, тем не менее я голосовал за hek2mgl как решение, так как я ограничен только sed, возможно, я должен был указать это. Спасибо, в любом случае! –

+0

@AlbertVonpupp Вы можете указать, в какой системе вы находитесь? Я не видел никакой системы, у которой 'sed', но не' awk' – Jotne

+0

Debian Jessie. Проблема заключается не только в этом, по какой-то неизвестной причине, некоторые строки строго не следуют примеру, который я объяснил, у некоторых есть CLRF после стиха, а на следующей строке он начинается только с «: verse». Мне все еще нужно понять, почему это происходит, я беру результаты из другой программы (diatheke). Мне нужно больше исследовать эту проблему. –

1

Это:

sed -r 's/.*([0-9]+:){2} ?//' testcase.txt 
+1

Спасибо за ваш ответ @Adam, мне понравилось ваше решение, тем не менее, я голосовал за hek2mgl как решение, так как он включал в себя основной параметр regex posix, который я нашел для него очень интересным для моего необходимо. Спасибо, в любом случае! –

+0

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

0

Это работа cut была изобретена сделать:

$ cut -d: -f3- file 
The song of songs, which is Solomon’s. 
For God so loved the world, that he gave his only begotten Son, that whosoever believeth in him should not perish, but have everlasting life. 
We therefore ought to receive such, that we might be fellowhelpers to the truth. 
+1

Спасибо за ваш ответ @ Эд Мортон, мне понравилось ваше решение, тем не менее я голосовал за hek2mgl как решение, так как ограничился только sed, возможно, я должен был указать это. Спасибо, в любом случае! –