РЕДАКТИРОВАТЬ: Вы опубликовали пример не имеет четкого разделителя, вам нужно найти четкое разделение между вашими заголовками и вашими последовательностями. Вы можете использовать несколько разрывов строк или не алфавитно-цифровые символы, такие как ','. Что бы вы ни выбрали, пусть WHITESPACE в следующем коде будет равен выбранному вами разделителю. Если вы застряли в имеющемся у вас формате, вам придется изменить следующую грамматику, чтобы игнорировать пробелы и разделять их заглавными буквами (это немного усложняет).
Простой способ (O (n ^ 2)?) - разделить файл, используя разделитель пробелов, давая вам массив заголовков и последовательностей (заголовок [i] = split_array [i * 2], sequence [i] = split_array [я * 2 + 1]). Для каждой последовательности выполните свое регулярное выражение.
Чуть более сложный способ (O (n)), учитывая грамматику БНФ, такую как:
file: block
| file block
;
block: heading sequence
heading: [A-Z][a-z]
sequence: [A-Z][a-z]
Попробуйте рекурсивный приличный анализ (псевдокод, я не знаю perl):
GLOBAL sequenceHeading, sequenceCount
GLOBAL substringLength = 5
GLOBAL substring = "FSFSD"
FUNC file ()
WHILE nextChar() != EOF
block()
printf ( "%d substrings in %s", sequenceCount, sequenceHeading )
END WHILE
END FUNC
FUNC block ()
heading()
sequence()
END FUNC
FUNC heading ()
in = popChar()
IF in == WHITESPACE
sequenceHeading = tempHeading
tempHeading = ""
RETURN
END IF
tempHeading &= in
END FUNC
FUNC sequence ()
in = popChar()
IF in == WHITESPACE
sequenceCount = count
count = 0
i = 0
END IF
IF in == substring[i]
i++
IF i > substringLength
count++
END IF
ELSE
i = 0
END IF
END FUNC
Для получения подробной информации о рекурсивном приличном разборе, посмотрите Давайте создадим компилятор или Википедия .