1
import re
st=input()  #The input string
ss=input()  #The substring to be searched
lss=len(ss)
lst=len(st)
x=lst-lss
for i in range(x):
    r=re.search(r'(%s)'%ss,st,i)
    if r:
        print(r.start(),r.end())

Above is code is response to a task. The task is:

A string S is given.

I need to find the indices of the start and end of string k in S.

If the input is:

aaadaa
aa

Output should be:

(0, 1)  
(1, 2)
(4, 5) 

I know the code which i have written is wrong because i am not getting the desired output.I went through and through again the line after for loop. I am not able to convince myself that it is wrong.I just want to know why the code after the for loop does not work? Can someone help me through?

Naveen Gabriel
  • 679
  • 2
  • 9
  • 25
  • 1
    I don't think you're supposed to pass `i` to `search` like that. the third argument to search is `flags`, not "index to start searching from", if that's what you're trying to do. – Kevin Feb 17 '17 at 16:39
  • You don't even need regex for this (and it's an overkill). Use standard `string.find()`. – zwer Feb 17 '17 at 17:31

1 Answers1

0

You should look at the re.search()'s document first, its third parameter is flag.


In your case, you are looking for overlapping results, I realized there is no straight forward solutions, so I wrote a recursion

import re
string = input()  # The input string
pattern = input()  # The substring to be searched

def match(pattern, string, startIdx=0):
    if startIdx <= len(string) - len(pattern):
        res = re.search(pattern, string[startIdx:])
        if res is not None:
            print(res.start() + startIdx, res.end() + startIdx - 1)
            return match(pattern, string, startIdx + res.start() + 1)


match(pattern, string)

whose output is

0 1
1 2
4 5

which should do the work as you've expected.


I checked preexisted solutions, they does not fits your request:

  • re.finditer can only do non-overlapping search.
  • re.findall do overlapping search, but fails to retrieve the index.
  • re.finditer and re.findall with look ahead returns matched text only.

I guess writing this own function is the best way to do it.


Good question, though.

Community
  • 1
  • 1
Chazeon
  • 546
  • 2
  • 14