2012-04-29 2 views
5

Я разбираю текст с большим количеством повторений простого шаблона. Текст в формате сценария для игры, например:Регулярное выражение для соответствия всем символам до следующего совпадения

SAMPSON 
I mean, an we be in choler, we'll draw. 

GREGORY 
Ay, while you live, draw your neck out o' the collar. 

настоящее время я использую шаблон ([A-Z0-9\s]+)\s*\:?\s*[\r\n](.+)[\r\n]{2}, который работает отлично (объяснение ниже), когда речь персонажа имеет разрывы строк в нем, кроме , Когда это происходит, имя персонажа захватывается успешно, но фиксируется только первая строка речи.

Включение однолинейного режима (для включения разрывов строк в .) просто создает один гигантский матч.

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

В идеале, я мог бы совместить все символы до тех пор, пока не будет повторяться весь шаблон.


Узор объяснил:

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

+0

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

+0

@mellamokb Я забыл включить последнюю часть рисунка, которая ищет пустую строку. Матч начинается с имени персонажа (все колпачки на собственной линии) и заканчивается на пустой строке после речи. – Nathan

+0

Я считаю, что в вашем образце текста отсутствуют двоеточия, регулярное выражение не работает с ним. –

ответ

0

Хорошо, я немного потрудился и нашел что-то, что работает. Это не очень элегантно, но он выполняет эту работу.

([A-Z0-9\s]+)\s*\:?\s*[\r\n]((.+[\r\n]?.*)+)[\r\n]{2} 

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

+0

Я просто хотел указать, я вставил регулярное выражение и пример из вашего вопроса в [инструмент тестирования регулярных выражений] (http://gskinner.com/RegExr/), а затем просто включил режим * dotall * (точки, совпадающие с символами новой строки), которые были решены твоя проблема. Странно, что не сработало для вас. – Hubro

1

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

results = "Insert script here".split(/^([A-Z]+)$/) 

О стандартах реализации совместимой, например, текст будет в конечном итоге в массиве, как так:

results[0] = "" 
results[1] = "SAMPSON"  
results[2] = "I mean, an we be in choler, we'll draw.    
" 
results[3] = "GREGORY"  
results[4] = "Ay, while you live, draw your neck out o' the collar. " 

Предостережение в том, что большинство браузеров являются пятнами на стандарте здесь. Вы можете использовать библиотеку XRegExp, чтобы получить кросс-платформенное поведение.

+0

В моем случае использование расщепления диалогов на отдельные строки не имеет смысла. Поскольку программа (и пользователь) взаимодействует с диалоговыми окнами в целом, мне просто нужно будет сшить их вместе, чтобы они были полезны. – Nathan

0

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

Вы должны были бы сделать findAll используя это регулярное выражение - он чувствителен к регистру:

((?:[A-Z]{2,}\s*:?\s*)+)\s+((?![A-Z]{2,}\s*:?\s*).+?[.?!]\s*)+ 

Объяснение:

  • ((?:[A-Z]{2,}\s*:?\s*)+) - первая группа захватывает верхнее имя дела человека - это Wi Л.Л. матч «Грегор», а также «MANFRED ВЕЛИЧАЙШАЯ:»
  • \s+ - по крайней мере один символ пробела
    Затем повторите по крайней мере один раз:
  • (?![A-Z]{2,}\s*:?\s*) - смотреть вперед, чтобы проверить, что следующий текст не верхний случай имя персонажа
  • .+?[.?!]\s* - сопрягать все, пока не найдете символ, завершающего предложение [.?!] и необязательно пробельные символы
Смежные вопросы