0
try:
    case_no  = re.search("Case Number:</span></td><td><span class=\"Value\">([^<]*?)<",br.response().read()).group(1)
except:
       try:
           try:
               case_no  = re.search("Citation Number:</span></td><td><span class=\"Value\">([^<]*?)<",br.response().read()).group(1)
            except:
               case_no  = re.search("Citation Number:</span></td><td><span class=\"Value\">([^<]*?)<",br.response().read()).group(1)
        except:
              case_no  = "N/A"

As you can see the above code is quite clumsy. I want to know if there is any way I can do like this.

try:
    XYZ
except:
    DOXYZ
except:
    DOXYZ

Basically I want to be able to use - "try X if exception then try Y if exception then try Z" without nesting too much statemtns.

Shubham
  • 21,300
  • 18
  • 66
  • 89
  • It seems that you have several regexp's that you want to try in order until one can be successfully applied or you get to the "N/A" part. Why not store the regexps in a list or tuple and iterate through it, catching whatever exceptions you want on the way? And yes, you can have several except blocks if you specify what exception to catch. – Fabian Fagerholm Aug 10 '10 at 07:36

7 Answers7

5

Probably you shouldn't be checking exception at all?

patterns = [
  "Case Number:</span></td><td><span class=\"Value\">([^<]*?)<",
  "Citation Number:</span></td><td><span class=\"Value\">([^<]*?)<",
  "Citation Number:</span></td><td><span class=\"Value\">([^<]*?)<"   # same as #2?
]
text = br.response().read()
case_no  = "N/A"
for pattern in patterns:
  res = re.search(pattern, text)
  if res:
    case_no = res.group(1)
    break
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
3

Yes, it is posible, as long as you define exception condition...

Like:

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except IOError as (errno, strerror):
    print "I/O error({0}): {1}".format(errno, strerror)
except ValueError:
    print "Could not convert data to an integer."
except:
    print "Unexpected error:", sys.exc_info()[0]
    raise

But, you must define the exception type.

Mp0int
  • 18,172
  • 15
  • 83
  • 114
  • 1
    This isn't really what the OP's trying to do, though. – detly Aug 10 '10 at 07:32
  • Yes, but basically, you can not execute try catch blocks as you execute switch or if blocks. Using if or switch is better that try-except. Because purpose of using try-catch is not suitable for a such condition... – Mp0int Aug 10 '10 at 07:42
3

A common idiom for the behavior you're looking for is something like:

try: foo()
except: pass

try: bar()
except: pass

But you should always catch a specific exception and make sure it makes sense. In your case it simply doesn't make sense - to see if the regular expression matched, test the result for None:

r = br.response().read()
PATTERN1="..."
PATTERN2="..."
PATTERN3="..."
mo = re.search(PATTERN1, r) or re.search(PATTERN2, r) or re.search(PATTERN3, r)
case_no = mo.group(1) if mo else "N/A"

For performance reasons you can precompile your regexes:

RE1 = re.compile("...")
RE2 = re.compile("...")
RE3 = re.compile("...")
mo = RE1.search(r) or RE2.search(r) or RE3.search(r)

Also, for your specific regex patterns you can easily combine them into one, and using a named group can help readability:

pat = r"""(Case|Citation) Number:</span></td><td><span class="Value">(?P<case_no>[^<]*?)<"""
mo = re.search(pat, r)
case_no = mo.group("case_no") if mo else "N/A"

And finally, using regular expressions to parse HTML is the road to disaster, consider using HTMLParser from the standard lib or Beautiful Soup.

Community
  • 1
  • 1
orip
  • 73,323
  • 21
  • 116
  • 148
2

No, it is not possible to do what you want. the semantics of multiple except clauses covers catching different types of exceptions that may be thrown from the same block of code. You must nest the statements or rethink your code to get the desired results.

This might be a case where it would be better to test for the preconditions that you expect to cause an exception.

if test1():
    #dox
elif test2():
    #doy
elif test3():
    #doz

etc.

I would also recommend against using catchall except: phrases except in very specialized circumstances where you know you need them.

aaronasterling
  • 68,820
  • 20
  • 127
  • 125
0

If you're doing the same or a similar thing in every try/except block, you might use a loop

case_no = "N/A"
for _ in range(3):
    try:
        case_no  = re.search("Case Number:</span></td><td><span class=\"Value\">([^<]*?)<",br.response().read()).group(1)
        break
    except SomeExplicitlyCaughtExceptions:
        pass

Of course it makes no sense in this form, because trying the same thing three times will yield the same result.

Johannes Charra
  • 29,455
  • 6
  • 42
  • 51
0

You'd be better off restructuring your code:

success = False

for _ in xrange(MAX_ATTEMPTS):
    try:
        XYZ
        success = True
        break
    except:
        pass

if not success:
   DOXYZ

It's better to explicitly specify the exception, though. Do you really want to catch KeyboardInterrupts?

detly
  • 29,332
  • 18
  • 93
  • 152
0

I'd avoid the exceptions if I were doing this:

count = 3
caseRe = re.compile("Case Number:</span></td><td><span class=\"Value\">([^<]*?)<")
while count > 0:
   text = br.response().read()
   mo = caseRe.search(text)
   if mo is None:
       count -= 1
       continue
   case_no  = mo.group(1)
   break

if count == 0:
    case_no = "N/A"
Douglas Leeder
  • 52,368
  • 9
  • 94
  • 137