2

I need a PHP Regex that can parse .strings files. In particular, it needs to be able to handle comments, blank lines, escaped characters and angle brackets.

Example of a .strings file:

/* string one */
"StringOne"="\"1\"";

"StringTwo"="<2>";

/* Bob Dillon */
"Bob"="Dillon";

By request, the desired output would be something such as:

Array( [StringOne] => "\"1\"" [StringTwo] => "<2>" [Bob] => "Dillon" )

All help is greatly appreciated!

hammerdr
  • 33
  • 4

2 Answers2

5

this?

    $r = '
    /* string one */
    "StringOne"="first \"string\"";

    "StringTwo"="2";

    /* Bob Dillon */
    "Bob"="Dillon";
    ';

    preg_match_all('~^\s*"((?:\\\\.|[^"])*)"[^"]+"((?:\\\\.|[^"])*)"~m', 
         $r, $matches, PREG_SET_ORDER);
    $parsed = array();
    foreach($matches as $m)
       $parsed[$m[1]] = $m[2];

    print_r($parsed);

prints

Array ( 
[StringOne] => first "string"
[StringTwo] => 2 
[Bob] => Dillon 
) 
alanaktion
  • 1,326
  • 1
  • 11
  • 18
user187291
  • 53,363
  • 19
  • 95
  • 127
  • That doesn't handle brackets or escaped characters (see updated question). Closer than what I got to though! – hammerdr Nov 06 '09 at 08:26
  • Sorry, I misspoke. It *does* handle angle brackets but it does NOT handle escaped parenthesis. – hammerdr Nov 06 '09 at 08:27
  • Updated question to provide example output. – hammerdr Nov 06 '09 at 08:33
  • It doesn't strip the escape characters (backslashes) for me. Using PHP 5.4.14. My output is: `... [StringOne] => first \"string\" ...`. Any ideas? – akashivskyy Jul 11 '13 at 14:35
  • I'll try this. Thanks. Makes you wonder though if there isn't already any class or library handling this. I'll see if I can find any. Using regex to solve this problem does not feel like an optimal solution. – Jonny Jul 08 '14 at 03:26
0

While I am using a PHP script as well, I am running it on a Mac so I thought I could whip up a Cocoa command line app to do the .strings parsing anyway. Which I did.

The code below is a command line utility which takes a filename parameter (the strings file) and spits out the content of that strings file as json (to stdout).

#import <Foundation/Foundation.h>

#import "NSDictionary+BVJSONString.h" // from http://stackoverflow.com/a/20262259/129202

#define ERRORCODE   (1)

int main(int argc, const char * argv[])
{

    @autoreleasepool {

        // insert code here...
        //NSLog(@"Hello, World!, argc: %d", argc);

        if (argc != 2) {
            NSLog(@"Specify file argument!");
            return ERRORCODE;
        }

        NSString* filepath = [NSString stringWithCString:argv[1] encoding:NSASCIIStringEncoding];

        NSError* error = nil;

        NSStringEncoding usedencoding;
        NSString* strings = [NSString stringWithContentsOfFile:filepath usedEncoding:&usedencoding error:&error];
        if (error) {
            NSLog(@"Error: %@", error);
            return ERRORCODE;
        }
        NSDictionary* dict = [strings propertyList];
        NSString* json = [dict bv_jsonStringWithPrettyPrint:NO];

        [json writeToFile:@"/dev/stdout" atomically:NO encoding:NSUTF8StringEncoding error:nil];
    }
    return 0;
}

It's a bit rough - it had better read from stdin or something - I'm not very used to writing these things so feel free to improve. Note that this is using Apple's own .strings parsing code, so should be better than most regexes.

Jonny
  • 15,955
  • 18
  • 111
  • 232