2016-11-30 22 views
1

У меня есть текст/файл субтитров, как показано ниже:Regex чтобы соответствовать строку, начинающуюся с цифры, только если та же строка содержит алфавитов позже

1 
00:00:58,178 --> 00:00:59,327 
Some text! 

2 
00:00:59,329 --> 00:01:01,819 
<i>Some text</i> 

3 
00:01:40,512 --> 00:01:41,629 
2350 some text. 

4 
00:01:41,631 --> 00:01:43,771 
Some text. 

Теперь я почти разобрался, как соответствовать фактической линии субтитров по ниже регулярное выражение:

^([^\d^\n].*) 

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

Как я могу это сделать, комбинируя с моим выше используемым регулярным выражением?

+0

Что делать, если линия подзаголовок просто номер? Также попробуйте этот подход: ['^ (?! \ D + $ | \ d {2}: \ d {2}: \ d {2}, \ d + -> \ d {2}: \ d {2} : \ d {2}, \ d + $). + '] (https://regex101.com/r/dPTc6v/2) –

+0

Может ли текст содержать двоеточия? Как 'Some: text'? – sigil

+0

Хорошо для этого случая (susbitle, начинающийся с номера). Я могу смело игнорировать его, так как регулярное выражение также столкнется с серийными номерами субтитров.Шансы на фактическую строку субтитров, содержащие только номера, являются относительно низкими по сравнению с целым файлом субтитров, но если этого можно избежать, это, безусловно, будет более благоприятным сценарием/идеальным вариантом. –

ответ

2

Update # 1

Это обновление сделано, чтобы принести огромный прирост производительности

Я полагаю, субтитры могут быть в нескольких строках:

^\d+:\d+:[^-]+-->.*\R+\K.+(?:\R.+)*(?=\s*(?:^\d+$|\z)) 

Пояснение:

^\d+:\d+:[^-]+-->.*  # Match time's line 
\R+\K     # One or more newlines (& forget all previous matched characters) 
.+      # Match next immediate line 
(?:\R.+)*    # And continuing lines of subtitle (if any) 
(?=\s*(?:^\d+$|\z))  # Up to a digit-only-line or end of input string 

Live demo

+0

Спасибо за отличный ответ, но это регулярное выражение также соответствует новой строке (которая служит разделом между субтитрами) после завершения содержимого, можно ли это как-то избежать? –

+1

Это делает этот ответ безупречным, и я думаю, что это будет работать с любыми уродливыми файлами субтитров, с которыми я когда-либо работаю в будущем. Даже тогда, если вы найдете какие-либо улучшения, вы можете улучшить его. Кстати, если вы найдете этот вопрос достойным, вы можете его поддержать. –

+1

Соответствие предыдущей строке - хорошая идея, потому что она потребляет строки, которые необходимо исключить. Поскольку этот тип файла всегда имеет одну и ту же структуру, и каждый блок заканчивается пустой строкой, вы можете даже позволить себе роскошь быть более уклончивым: '^ \ d +:. * \ R \ K. + (?: \ R. +) * ' –

1

Я предлагаю такой подход, который заключается в игнорировании всех линий, которые являются только цифрой или равны период SRT метки времени:

^(?!\d+$|\d{2}:\d{2}:\d{2},\d+ --> \d{2}:\d{2}:\d{2},\d+$).+ 

См this regex demo

Детали:

  • ^ - начало строки
  • (?! - начало отрицательного предпросмотра, который потерпит неудачу в матче, если шаблон найден сразу справа:
    • \d+$ - 1+ цифры до конца строки
    • | - или
    • \d{2}:\d{2}:\d{2},\d+ --> \d{2}:\d{2}:\d{2},\d+$ - в --> отделенных временных меток
  • ) - конец упреждающей выборки
  • .+ - матч т он весь непустой строки
+0

Это отличный ответ, спасибо большое. Не удаляйте его, вы можете отредактировать/улучшить его. –

+0

Я вижу, что вы предпочитаете более точное регулярное выражение. Обратите внимание, что регулярное выражение revo использует шаблон совпадения с ленивыми точками (вам не нужно '[\ s \ S]', если вы замените его на '.' И используете модификатор DOTALL), который вместе с lookahead в конце является ресурсом потребительский шаблон. Используйте ['^ \ d +: \ d +: [^ -] + ->. * \ R \ K. + (?: \ R (?! \ D + $). *) *'] (Https: // www .regex101.com/г/jWOqAq/4). Обратите внимание, что количество шагов уменьшается с этой версией 4 раза. На самом деле, я бы предпочел более подробную часть, соответствующую метке времени ('\ d {2}: \ d {2}: \ d {2}, \ d + -> \ d {2}: \ d {2} : \ д {2}, \ d + $ '). –

+0

Обратите внимание, что '[^ -]' соответствует разрыву строки, поэтому вы можете заменить его на '[^ - \ r \ n]'. –