Search code examples
pythonregexstring-parsingnslocalizedstring

Regex expression to find all occurences of 'NSLocalizedString' in file contents


Test cases:

// With text and comment
NSLocalizedString(@"Example Text", @"Example Comment");

// With text and no comment
NSLocalizedString(@"Example, text", nil) 

// With text and comment with paranthesis
NSLocalizedString(@"Example text", @"Example (with paranthesis) comment") 

// With property and no comment
NSLocalizedString(test, nil)

// With property and comment
NSLocalizedString(test, @"Example comment")

// Inline
NSLocalizedString(@"Error", nil) NSLocalizedString(@"Change settings", @"Option to change HTTP Post settings") NSLocalizedString(@"Cancel", nil)

What I'm looking for: one match per NSLocalizedString occurance, with two capture groups (key and comment). Key may have a value or be nil.

What I've tried: r'NSLocalizedString\((.*)\s*,\s*(.*)\)'

This works for most of the cases, except for the last one (Inline) because it matches at the last comma.

Regex101: https://regex101.com/r/4OJgU2/6


Solution

  • You may solve the problem using

    r'(?s)NSLocalizedString\(\s*(@\"[^\"\\]*(?:\\.[^\"\\]*)*\"|\w+)\s*,\s*(@\"[^\"\\]*(?:\\.[^\"\\]*)*\"|\w+)\)'
    

    and the replacement

    r'NSLocalizedStringWithDefaultValue(@"elementID", nil, [NSBundle mainBundle], \1, \2)'
    

    Details

    • NSLocalizedString\( - NSLocalizedString( substring
    • \s* - 0+ whitespaces
    • (@\"[^\"\\]*(?:\\.[^\"\\]*)*\"|\w+) - Group 1:
      • @\"[^\"\\]*(?:\\.[^\"\\]*)*\" - @" followed with 0+ chars other than " and \ followed with 0+ repetitions of any escaped char followed with 0+ chars other than " and \ and then a " (it is the Obj-C string literal matching pattern)
      • | - or
      • \w+ - 1+ word chars
    • \s*,\s* - , enclosed with 0+ whitespaces
    • (@\"[^\"\\]*(?:\\.[^\"\\]*)*\"|\w+) - Group 2
    • \) - a ) char.

    See the Python demo:

    import re
    strs = ['NSLocalizedString(@"Example Text", @"Example Comment");', 'NSLocalizedString(@"Example, text", nil)', 'NSLocalizedString(@"Example text", @"Example (with paranthesis) comment")', 'NSLocalizedString(test, nil)', 'NSLocalizedString(test, @"Example comment")', 'NSLocalizedString(@"Error", nil) NSLocalizedString(@"Change settings", @"Option to change HTTP Post settings") NSLocalizedString(@"Cancel", nil)']
    pat = re.compile(r'NSLocalizedString\(\s*(@\"[^\"\\]*(?:\\.[^\"\\]*)*\"|\w+)\s*,\s*(@\"[^\"\\]*(?:\\.[^\"\\]*)*\"|\w+)\)', re.DOTALL)
    repl = r'NSLocalizedStringWithDefaultValue(@"elementID", nil, [NSBundle mainBundle], \1, \2)'
    for s in strs:
        print('----------------------------------\n{}\nVVVVVVVVVVVVVVVVVVVV'.format(s))
        res = pat.sub(repl, s)
        print(res)
    

    Output:

    ----------------------------------
    NSLocalizedString(@"Example Text", @"Example Comment");
    VVVVVVVVVVVVVVVVVVVV
    NSLocalizedStringWithDefaultValue(@"elementID", nil, [NSBundle mainBundle], @"Example Text", @"Example Comment");
    ----------------------------------
    NSLocalizedString(@"Example, text", nil)
    VVVVVVVVVVVVVVVVVVVV
    NSLocalizedStringWithDefaultValue(@"elementID", nil, [NSBundle mainBundle], @"Example, text", nil)
    ----------------------------------
    NSLocalizedString(@"Example text", @"Example (with paranthesis) comment")
    VVVVVVVVVVVVVVVVVVVV
    NSLocalizedStringWithDefaultValue(@"elementID", nil, [NSBundle mainBundle], @"Example text", @"Example (with paranthesis) comment")
    ----------------------------------
    NSLocalizedString(test, nil)
    VVVVVVVVVVVVVVVVVVVV
    NSLocalizedStringWithDefaultValue(@"elementID", nil, [NSBundle mainBundle], test, nil)
    ----------------------------------
    NSLocalizedString(test, @"Example comment")
    VVVVVVVVVVVVVVVVVVVV
    NSLocalizedStringWithDefaultValue(@"elementID", nil, [NSBundle mainBundle], test, @"Example comment")
    ----------------------------------
    NSLocalizedString(@"Error", nil) NSLocalizedString(@"Change settings", @"Option to change HTTP Post settings") NSLocalizedString(@"Cancel", nil)
    VVVVVVVVVVVVVVVVVVVV
    NSLocalizedStringWithDefaultValue(@"elementID", nil, [NSBundle mainBundle], @"Error", nil) NSLocalizedStringWithDefaultValue(@"elementID", nil, [NSBundle mainBundle], @"Change settings", @"Option to change HTTP Post settings") NSLocalizedStringWithDefaultValue(@"elementID", nil, [NSBundle mainBundle], @"Cancel", nil)