Извлечь с помощью регулярного выражения

Я новичок в Ruby, Regex и Stackoverflow. xD Вот моя проблема:

Я хочу использовать регулярное выражение для извлечения фраз, состоящих из последовательных слов со стандартными символами ASCII, отдельно от других во вьетнамских текстах.

Другими словами, фразы только с символами \w, например:

Mình rất thích con Sharp này (mặc dù chưa xài bao h nhưng chỉnghe cac pac nói minh đã thấy phê lòi mắt rồi). Cac bạn cho minh hỏi 1 câu (cac bạn đừng chê mình ngu nhé tội nghiệp minh): cái máy này đem sang Anh dùng mạng Vodafone la dùng v` tư ah? Nếu dùng được ben Anh mà không phai chọc ngoay j thì minh mua một cái

Меня не волнует его значение, я хочу получить массив хэшей, содержащий результаты с двумя парами: value => значение извлеченных фраз, start_position => позиция первого символа.

Согласно примеру о, должно быть так: [{:value=>"con Sharp", :starting_position => 16}, {:value=>"bao h", :starting_position => blah blah}... ]

Это означает, что все слова, содержащие символы \W, такие как «mình», «rất», «thích» и т. д., будут отклонены.

Пример выше с этим регулярным выражением на rubular.com для Ruby 1.9.2:

\b[\w|\s]+\b

Я почти получил нужные фразы (кроме пробелов), но, похоже, они не работают на моем Ruby, который также 1.9.2p290, с использованием 64-разрядной версии Win 7.

Любые идеи будут высоко оценены. Спасибо заранее.


person Thiem Nguyen    schedule 30.03.2012    source источник


Ответы (1)


Согласно rubular, похоже, что \w соответствует всем буквам и цифрам ascii (и подчеркнутым), но \b хорошо работает для всех букв Unicode. Это немного сбивает с толку.

Однако вам нужны все последовательности слов ASCII. Это должно соответствовать им:

/\b[a-z]+\b(?:\s+[a-z]+)*\b/i

Рабочий пример: http://www.rubular.com/r/1iewl7MpJe

Краткое объяснение:

  • \b[a-z]+\b - первое слово ASCII.
  • (?:\s+[a-z]+) - любое количество пробелов и слов - каждый раз не менее одного пробела и одной буквы.
  • \b - чтобы последнее слово не заканчивалось в середине другого слова, например n в "con Sharp này".

Я не уверен в получении хэша, но вы можете получить все MatchDatas, аналогично:
Как получить данные соответствия для всех вхождений регулярного выражения Ruby в строку?

s = "hello !@# world how a9e you"
r = /\b[a-z]+\b(?:\s+[a-z]+)*\b/i

matches = s.to_enum(:scan, r).map { Regexp.last_match }
           .map {|match| [match.to_s(), match.begin(0)]}
puts matches 

Вот пример ideone: http://ideone.com/YRZE5.

person Kobi    schedule 30.03.2012
comment
Похоже, \b\w+\b(?:\s+\w+)*\b тоже сработает. Я не уверен, почему я думал, что \w соответствует всем буквам Unicode... В любом случае, я проверю кое-какую документацию. Я не могу найти его в ruby-doc.org/core- 1.9.3/Regexp.html - person Kobi; 30.03.2012
comment
Замечательно! Большое спасибо. Кстати, как я могу получить массив результатов, как описано выше, используя Ruby? Я попробовал сканировать и сопоставить, но не знал, что с ними делать? - person Thiem Nguyen; 30.03.2012
comment
@ThiemNguyen - Спасибо! Я добавил пример для получения необходимых данных. Я на самом деле не знаю Ruby, кроме как отвечать на вопросы Stack Overflow, так что вы, вероятно, справитесь лучше меня :P - person Kobi; 30.03.2012
comment
Мне удалось извлечь их с помощью Ruby и вашего регулярного выражения. Заранее спасибо. хД - person Thiem Nguyen; 01.04.2012