re question - finiding matching ()

Mark McEahern mark at mceahern.com
Sun Jan 18 12:05:20 EST 2004


On Sun, 2004-01-18 at 09:51, Miki Tebeka wrote:
> Hello All,
> 
> To all of you regexp gurus out there...
> 
> I'd like to find all of the sub strings in the form "add(.*)"
> The catch is that I might have () in the string (e.g. "add((2 * 2), 100)"), 

The pattern you have is so simple and the necessary regex (it seems to
me) so unnecessarily complex (for a 100% regex solution) that I think
using only regex's for this problem is overkill.  Anyway, here's a
test-based approach:

#!/usr/bin/env python

import re
import unittest

def findOperands(verb, text):
    """Find operands in text for verb.

    E.g., findOperands('add', 'add(1, 2, 3)') == ['1', '2', '3']

    """
    raw = '%s\((.*)\)' % (verb,)
    pat = re.compile(raw)
    matches = pat.findall(text)
    if not matches:
        raise RuntimeError('No matches found for pattern %s.' % (raw,))
    assert len(matches) == 1
    match = matches[0]
    operands = match.split(',')
    for i, item in enumerate(operands):
        operands[i] = item.strip()
    return operands
    
class test(unittest.TestCase):

    def test(self):
        text = 'add(2, 3)'
        operands = findOperands('add', text)
        expected = ['2', '3']
        self.assertEquals(operands, expected)

        text = 'add((2 * 2), 100)'
        operands = findOperands('add', text)
        expected = ['(2 * 2)', '100']
        self.assertEquals(operands, expected)

        text = 'add(1, 2, 3)'
        operands = findOperands('add', text)
        expected = ['1', '2', '3']
        self.assertEquals(operands, expected)

        text = 'multiply(1, 2, 3, 4)'
        operands = findOperands('multiply', text)
        expected = ['1', '2', '3', '4']
        self.assertEquals(operands, expected)

        text = 'add 2, 3'
        self.assertRaises(RuntimeError, findOperands, 'add', text)
        
unittest.main()






More information about the Python-list mailing list