13

I am trying to find a way to match a pattern p in a string s in python.

s = 'abccba'
ss = 'facebookgooglemsmsgooglefacebook'
p = 'xyzzyx'
# s, p -> a, z  # s and p can only be 'a' through 'z'

def match(s, p):
   if s matches p:
      return True
   else:
      return False

match(s, p) # return True
match(ss, p) # return True

I just tried:

import re

s = "abccba"
f = "facebookgooglemsmsgooglefacebook"
p = "xyzzyx"

def fmatch(s, p):
    p = re.compile(p)
    m = p.match(s)
    if m:
        return True
    else:
        return False

print fmatch(s, p)
print fmatch(f, p)

Both return false; they are supposed to be true.

5
  • Does if p in s work for you? Commented May 20, 2015 at 19:07
  • The keywords in Python are True and False. Capitalization is important. Commented May 20, 2015 at 19:08
  • Related: codereview.stackexchange.com/q/21532 Commented May 20, 2015 at 19:08
  • No. As in the example, each element in p and s can be different. Each element in the pattern can be 1 char in the string or 1000 chars. Commented May 20, 2015 at 19:09
  • Are you trying to perform a dynamic pattern match, where "xyzzyx" means that x, y, and z can represent any string but then must appear in specified sequence? Commented May 20, 2015 at 19:40

4 Answers 4

7

I convert your pattern into a regular expression that can then be used by re.match. For example, your xyzzyx becomes (.+)(.+)(.+)\3\2\1$ (the first occurrence of each letter becomes a capture group (.+), and subsequent occurences become the proper back reference).

import re

s = 'abccba'
ss = 'facebookgooglemsmsgooglefacebook'
p = 'xyzzyx'

def match(s, p):
    nr = {}
    regex = []
    for c in p:
        if c not in nr:
            regex.append('(.+)')
            nr[c] = len(nr) + 1
        else:
            regex.append('\\%d' % nr[c])
    return bool(re.match(''.join(regex) + '$', s))

print(match(s, p))
print(match(ss, p))
Sign up to request clarification or add additional context in comments.

Comments

3

You could make use of regular expressions.
Have a look here for some examples: Link

I think you could use re.search()

Ecample:

import re 

stringA = 'dog cat mouse'
stringB = 'cat'

# Look if stringB is in stringA
match = re.search(stringB, stringA)

if match:
    print('Yes!')

1 Comment

search() is not correct. Each char in p is an element of the pattern. In the string that element can be of any char(a-z) or any length.
1

If I'm understanding your question, you're looking for a pythonic approach to pattern matching across a set of strings.

Here is an example demonstrating the use of list comprehensions to achieve this goal.

I hope it helps you reach your goal. Please let me know if I can help further. - JL

Demonstrate No Match Found

>>> import re
>>> s = ["abccba", "facebookgooglemsmsgooglefacebook"]
>>> p = "xyzzyx"
>>> result = [ re.search(p,str) for str in s ] 
>>> result
[None, None]

Demonstrate Combination of Matches and No Match in the result

>>> p = "abc"
>>> result = [ re.search(p,str) for str in s ] 
>>> result
[<_sre.SRE_Match object at 0x100470780>, None]
>>> [ m.group(0) if m is not None else 'No Match' for m in result ]
['abc', 'No Match']
>>> [ m.string if m is not None else 'No Match' for m in result ]
['abccba', 'No Match']

Demonstrate single statement

>>> [ m.string if m is not None else 'No Match' for m in [re.search(p,str) for str in s] ]
['abccba', 'No Match']

2 Comments

Your question is correct but the result is wrong. "abccba" and "xyzzyx" are a clear match to a human.
I think I understand now. But I think, then that "facebookgooglemsmsgooglefacebook" should really be "facebookgooglemsmssmsgooglefacebook" to be a match, since the middle item must repeat. Then the next step is to recode the match pattern to a standard base representations (e.g. "xyzzyx" should be recoded to "abccba", where a="x", b="y", c="z"). This would take care of one match. The second match would need to allow for recoding of any length string. You would find this algorithm, no doubt, in basic compression schemes, which first build an optimal symbol table, then compress the string.
0

Compile a Python regular expressions object for some pattern of interest and then pass the string to its Match(string) method. You'll want to use a match object if you need a boolean output: https://docs.python.org/3/library/re.html#match-objects

Example: Check string s for any word character (that is, alphanumerics)

def match_string(s):
    ##compile a regex for word characters
    regex = re.compile("\\w") 
    ##return the result of the match function on string 
    return re.match(s)

Hope it helps!

4 Comments

It will be better off with an example.
I have fixed the above problem description
So, using the documentation provided, write a method that accepts s and p, compiles a regex for pattern p, and matches it to s. Learning to read and implement from API documentation will serve you greatly in the long-run.
Is regex the best way? I have been trying and it returns False.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.