Как сделать необязательную группу захвата с помощью метода сканирования Ruby? - PullRequest
0 голосов
/ 15 декабря 2011

У меня есть такое регулярное выражение:

(.*?)("DisplayName":.*?)(,)(.*?"Groups":?)?(\[.*?\])?(,)(.*?"Phones":)?(\[.*?\])?(.*?\},)?

, с помощью которого я хочу обработать строку, подобную этой:

{"Affinity": 20, "DisplayName": "Moe Larry", "Emails": [{"Address": "moelarry@gmail.com", "Primary": true, "Type": {"Id ":" HOME "}}]," FullName ": {" FamilyName ":" Larry "," GivenName ":" Moe "," Unstructured ":" Moe Larry "}," Groups ": [{" id ": "^ Mine"}], "Id": "1234567890", "MailsSent": 0, "Name": "Moe Larry", "Phones": [{"Number": "555-999-6661", "Type ": {" Идентификатор ":" МОБИЛЬНЫЕ "}}]," ProfileLink ":" "}, {" Affinity ": 20," отображаемое_имя ":" stoogesarefunny», "Письма": [{ "Адрес": "stoogesarefunny" , "Primary": истинно}], "EvergreenPhoto": "/ фото / частный / adflk; jsd394u75430o8752380974321jtkasdljf8937489213749832654", "Id": "834754hthbf83744823f", "MailsSent": 0}, { "Affinity": 20, "DisplayName": "stoogesarefunny@gmail.com", "Письма": [{ "Адрес": "stoogesarefunny@gmail.com", "Primary": истинно}], "EvergreenPhoto": "/ фотографии / частный / asdfAJDKLJSFIOEJHLTHSJKLDF234987s897KJHSDFKJHDF89273473ASLKJDLSKJIFEIH", "Id" : "834754hthbf83744823f", "MailsSent": 0, "ProfileLink": "https://profiles.google.com/stoogesarefunny"},{"Affinity":20,"DisplayName":"Shemp","FullName":{"GivenName":"Shemp","Unstructured":"Shemp"},"Groups":[{"id":"^Mine"}],"Id":"1234567890","MailsSent":0,"Name":"Shemp","Phones":[{"Number":"+15553085671","Type":{"Id":"OTHER"}}]},{"Affinity":20,"DisplayName":"ClownFace","FullName":{"GivenName":"ClownFace","Unstructured":"ClownFace"},"Groups":[{"id":"^Mine"}],"Id":"1234567890","MailsSent":0,"Name":"ClownFace","Phones":[{"Number":"+15556064040","Type":{"Id":"OTHER"}}]},

Это действительно ужасно, я знаю. Хотелось бы найти канал XML, но сейчас это не вариант.

Все, что меня волнует, это DisplayName, Groups и Phones. Мне нужно извлечь и сохранить их в массиве массивов. Группы захвата для групп и телефонов должны быть необязательными, поскольку они есть не у всех контактов. Тем не менее, мое регулярное выражение дает мне:

Result 1

1. {"Affinity":20,
2. "DisplayName":"Moe Larry"
3. ,
4. "Emails":[{"Address":"moelarry@gmail.com","Primary":true,"Type":{"Id":"HOME"}}],"FullName":{"FamilyName":"Larry","GivenName":"Moe","Unstructured":"Moe Larry"},"Groups":
5. [{"id":"^Mine"}]
6. ,
7. "Id":"1234567890","MailsSent":0,"Name":"Moe Larry","Phones":
8. [{"Number":"555-999-6661","Type":{"Id":"MOBILE"}}]
9. ,"ProfileLink":""},

Result 2

1. {"Affinity":20,
2. "DisplayName":"stoogesarefunny"
3. ,
4. "Emails":[{"Address":"stoogesarefunny","Primary":true}],"EvergreenPhoto":"/photos/private/adflk;jsd394u75430o8752380974321jtkasdljf8937489213749832654","Id":"834754hthbf83744823f","MailsSent":0},{"Affinity":20,"DisplayName":"stoogesarefunny@gmail.com","Emails":[{"Address":"stoogesarefunny@gmail.com","Primary":true}],"EvergreenPhoto":"/photos/private/asdfAJDKLJSFIOEJHLTHSJKLDF234987s897KJHSDFKJHDF89273473ASLKJDLSKJIFEIH","Id":"834754hthbf83744823f","MailsSent":0,"ProfileLink":"https://profiles.google.com/stoogesarefunny"},{"Affinity":20,"DisplayName":"Shemp","FullName":{"GivenName":"Shemp","Unstructured":"Shemp"},"Groups":
5. [{"id":"^Mine"}]
6. ,
7. "Id":"1234567890","MailsSent":0,"Name":"Shemp","Phones":
8. [{"Number":"+15553085671","Type":{"Id":"OTHER"}}]
9. },

Result 3

1. {"Affinity":20,
2. "DisplayName":"ClownFace"
3. ,
4. "FullName":{"GivenName":"ClownFace","Unstructured":"ClownFace"},"Groups":
5. [{"id":"^Mine"}]
6. ,
7. "Id":"1234567890","MailsSent":0,"Name":"ClownFace","Phones":
8. [{"Number":"+15556064040","Type":{"Id":"OTHER"}}]
9. },

Очевидно, что все контактные данные Шемпа включаются в данные stoogesarefunny@gmail.com, потому что мое регулярное выражение продолжает разбрасываться, пока не попадет в Группу Шемпса, вместо того, чтобы остановиться перед его отображаемым именем и начать заново. Помощь

П.С .: Нет, я не планирую спасать все эти группы, в конечном счете, просто я могу изучить, что происходит.

1 Ответ

6 голосов
/ 15 декабря 2011

Ваш ввод выглядит как JSON , для которого уже есть синтаксические анализаторы для Ruby:

gem install json

Затем в ruby:

data = JSON.parse(string)

Вы можете получить доступ к data непосредственно как хеш-объект, например:

data = '
  {"Affinity":20,
    "DisplayName":"Moe Larry",
    "Emails":[{"Address":"moelarry@gmail.com","Primary":true,"Type":{"Id":"HOME"}}],
    "FullName":{"FamilyName":"Larry","GivenName":"Moe","Unstructured":"Moe Larry"},
    "Groups":[{"id":"^Mine"}],
    "Id":"1234567890",
    "MailsSent":0,
    "Name":"Moe Larry",
    "Phones":[{"Number":"555-999-6661","Type":{"Id":"MOBILE"}}],
    "ProfileLink":""
  }
'

require 'json'
user = JSON.parse(data)
user.class                    # => Hash
user.keys                     # => ["Affinity", "DisplayName", "Emails", "FullName", "Groups", "Id", "MailsSent", "Name", "Phones", "ProfileLink"]
user['Affinity']              # => 20
user['DisplayName']           # => "Moe Larry"
user['Emails']                # => [{"Address"=>"moelarry@gmail.com", "Primary"=>true, "Type"=>{"Id"=>"HOME"}}]
user['Emails'].class          # => Array
user['Emails'][0]             # => {"Address"=>"moelarry@gmail.com", "Primary"=>true, "Type"=>{"Id"=>"HOME"}}
user['Emails'][0]['Address']  # => "moelarry@gmail.com"
...