70

Suppose I want a regular expression that matches both "Sent from my iPhone" and "Sent from my iPod". How do I write such an expression?

I tried things like:

re.compile("Sent from my [iPhone]|[iPod]") 

but doesn't seem to work.

Cédric Julien
  • 78,516
  • 15
  • 127
  • 132
Henley
  • 21,258
  • 32
  • 119
  • 207
  • 2
    Looks like you would greatly benefit by brushing up on the basics. See: [Python Regular Expression HOWTO](http://docs.python.org/dev/howto/regex.html) and/or [regular-expressions.info](http://www.regular-expressions.info/). – ridgerunner Dec 22 '11 at 22:10
  • You can use https://pythex.org to quickly and easily experiment with your Python regular expressions. I find this to be very helpful whenever I'm struggling to find the correct syntax. – J Jones Feb 19 '19 at 00:04

2 Answers2

102
re.compile("Sent from my (iPhone|iPod)")

See in action here.

Saikat
  • 14,222
  • 20
  • 104
  • 125
Paul
  • 139,544
  • 27
  • 275
  • 264
  • 29
    Or even "Sent from my iP(:?hone|[ao]d)", which includes the iPad as well. – Chris Tonkinson Dec 22 '11 at 20:59
  • How is this working? The output is: Out[25]: ['iPhone'] – lapinkoira Oct 19 '16 at 13:47
  • 7
    @lapinkoira The output of what? Do you really think this warrants a down vote when it works for the person who asked the question and everyone else who found it, but doesn't work for a specific way that you're using it that has nothing to do with the original question? – Paul Oct 19 '16 at 14:55
  • "Sent from my " is part of the regex and is being ignored in the output without the ?: OP wants to match "Sent from my iPhone" or "Sent from my iPod" strings which are contained somewhere else with more text and the output is just IPhone or IPod. Futhermore, if you are looking for Python regular expressions OR and want to look for one pattern OR other one this is not working but the below answer. I dont see why your answer is different for example from re.compile("(iPhone|iPod)") – lapinkoira Oct 19 '16 at 15:16
  • 4
    @lapinkoira My answer wouldn't match the strings `iPhone` or `iPod` on there own. It will only match `Sent from my iPhone` or `Sent from my iPod`, just like the OP wants. There is a difference between what is matched and what is captured, and the OP only asked about what is matched. `re.compile("(iPhone|iPod)")` would find a match in the string `Red iPhone`, but my answer doesn't, since my answer requires the string to have `Sent from my ` before either `iPhone` or `iPod`. Btw, regular expressions don't output anything, so I'm not sure what you mean by that. – Paul Oct 19 '16 at 16:14
  • 1
    The other answer just suppresses capturing the group, so while both of our answers give `match.group(0) == 'Sent from my iPhone'`, mine also allows you to get just the part that was captured separately **if you want** using `match.group(1) == 'iPhone'`, whereas `match.group(1)` in the other answer would throw an `IndexError: no such group`. – Paul Oct 19 '16 at 16:20
  • 2
    @ChrisTonkinson `:?` should be `?:` in your (useful!) comment. – Bálint Sass Apr 14 '21 at 12:42
34
re.compile("Sent from my (?:iPhone|iPod)")

If you need to capture matches, remove the ?:.

Fyi, your regex didn't work because you are testing for one character out of i,P,h,o,n,e or one character out of i,P,o,d..

ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
  • 3
    No they are testing for "Sent from my " and then one of the characters i, P, h, o, n, or e; OR one of the characters i, P, o, or d. The vertical bar for OR is topmost scope, and the left hand side has "Sent from my" in it but the right hand side does not. – PaulMcG Dec 22 '11 at 23:29