2014-02-17 3 views
0

Я использую следующее регулярное выражение, чтобы разделить текст на определенные препинания, но он не работает с кавычками.Ruby regex to split text

text = "\"Hello my name is Kevin.\" How are you?" 
text.scan(/\S.*?[...!!??]/) 

=> ["\"Hello my name is Kevin.", "\" How are you?"] 

Моя цель состоит в том, чтобы произвести следующий результат, но я не очень хорошо разбираюсь в выражениях регулярных выражений. Любая помощь будет принята с благодарностью.

=> ["\"Hello my name is Kevin.\"", "How are you?"] 
+0

вход не является допустимым английским текст, в качестве примера, или вы выбираете плохой пример? – fotanus

+0

@mbratch Спасибо за ссылку. Однако 'text.split (/ ([... !! ??]) \ s + /)' yields '=> [" \ "Привет, меня зовут Кевин. \" Как вы? "]', Который не является что я ищу. – diasks2

+0

Ваш вопрос непонятен. В результате вы заявили, что хотите; строка разделяется пунктуацией. Каково правило, которое заставляет вас хотеть иначе? – sawa

ответ

2
text.scan(/"(?>[^"\\]+|\\{2}|\\.)*"|\S.*?[...!!??]/) 

Идея заключается в том, чтобы прежде, чем проверить цитируемые части. Подшаблон немного более разработан, чем простой "[^"]*", чтобы иметь дело с экранированными кавычками (* см. В конце более эффективный шаблон).

детали модели:

"    # literal: a double quote 
(?>   # open an atomic group: all that can be between quotes 
    [^"\\]+ # all that is not a quote or a backslash 
    |   # OR 
    \\{2}  # 2 backslashes (the idea is to skip even numbers of backslashes) 
    |   # OR 
    \\.  # an escaped character (in particular a double quote) 
)*   # repeat zero or more times the atomic group 
"    # literal double quote 
|    # OR 
\S.*?[...!!??] 

, чтобы иметь дело с одной цитатой, Вы можете добавить: '(?>[^'\\]+|\\{2}|\\.)*'| шаблону (наиболее эффективным), но если вы хотите сделать его короче, вы можете написать это:

text.scan(/(['"])(?>[^'"\\]+|\\{2}|\\.|(?!\1)["'])*\1|\S.*?[...!!??]/) 

, где \1 является обратной ссылкой на первую группу захвата (найденная цитата) и (?!\1) означает, что не следует найденная цитата.

(*) вместо того, чтобы писать "(?>[^"\\]+|\\{2}|\\.)*", вы можете использовать "[^"\\]*+(?:\\.[^"\\]*)*+", что является более эффективным.

+2

вы можете объяснить это регулярное выражение пожалуйста. Это будет действительно здорово для noobs, таких как us – aelor

+0

Спасибо! Если бы я также хотел включить одинарные кавычки, есть ли более суровый способ написать его, чем просто иметь другое или заявление? – diasks2

1

Добавить дополнительную кавычку (["']?) к схеме:

text.scan(/\S.*?[...!!??]["']?/) 
# => ["\"Hello my name is Kevin.\"", "How are you?"]