views:

210

answers:

2

I need to parse an extremely complex string of characters to extract a particular section of it, which contains a foreign key to a database (the snippet comes from a product called Interspire Email Marketer and contains some weird logic to filter a contact list).

The string in question is as follows (yes, I realize it's extremely weird. That's how the system stores it):

a:2:{s:5:"Lists";a:1:{i:0;s:1:"6";}s:5:"Rules";a:1:{i:0;a:3:
{s:4:"type";s:5:"group";s:9:"connector";s:3:"and";s:5:"rules";a:1:{i:0;a:3:
{s:4:"type";s:4:"rule";s:9:"connector";s:3:"and";s:5:"rules";a:2:   
{s:8:"ruleName";s:3:"100";s:12:"ruleOperator";s:7:"isempty";}}}}}}

The part I need is {i:0;s:1:"<here>";} but it can be more than just a single character. How can I parse this weird string and extract the number I need with Ruby?

+3  A: 

You can use regular expressions:

s = 'a:2:{s:5:"Lists";a:1:{i:0;s:1:"6";}s:5:"Rules";a:1:{i:0;a:3:
    {s:4:"type";s:5:"group";s:9:"connector";s:3:"and";s:5:"rules";a:1:{i:0;a:3:
    {s:4:"type";s:4:"rule";s:9:"connector";s:3:"and";s:5:"rules";a:2:   
    {s:8:"ruleName";s:3:"100";s:12:"ruleOperator";s:7:"isempty";}}}}}}'
print $1 if s =~ /\{i:0;s:1:\"(\d+)\";\}/ // prints 6
JG
+2  A: 

This string is generated by PHP - so if you have access to PHP, it is better to use it to parse it, since it is native there:

$str='a:2:{s:5:"Lists";a:1:{i:0;s:1:"6";}s:5:"Rules";a:1:{i:0;a:3:{s:4:"type";s:5:"group";s:9:"connector";s:3:"and";s:5:"rules";a:1:{i:0;a:3:{s:4:"type";s:4:"rule";s:9:"connector";s:3:"and";s:5:"rules";a:2:{s:8:"ruleName";s:3:"100";s:12:"ruleOperator";s:7:"isempty";}}}}}}';
$array = unserialize($str);
return $array['Lists'][0];

returns 6, which is the <here> part.

The array looks like:

array (
  'Lists' => 
  array (
    0 => '6',
  ),
  'Rules' => 
  array (
    0 => 
    array (
      'type' => 'group',
      'connector' => 'and',
      'rules' => 
      array (
        0 => 
        array (
          'type' => 'rule',
          'connector' => 'and',
          'rules' => 
          array (
            'ruleName' => '100',
            'ruleOperator' => 'isempty',
          ),
        ),
      ),
    ),
  ),
)

you can call PHP from ruby using 'system' command, or even put it as a web service to do the parsing - all depends on your case.

yhager