0

I have a string, an array which contains possible end characters for that string, and a block of text to parse. For example:

stringText = "something"
endChars = [",", ".", ";", " "]
textBlock = "This string may contain something;"

In a one line if statement, I want to check if textBlock contains the stringText followed by any one of the endChars. I'm pretty sure I can do this with the built in any function in Python 2.7, but my efforts so far have failed. I have something similar to this:

if re.search(stringText + any(endChar in endChars), textBlock, re.IGNORECASE):
    print("Match")

I've seen this post, however I'm struggling to apply it to my check above. Any help doing to would be appreciated.

EDIT:

In addition to the above, is it possible to determine which of the endChars was found in the string? Using @SCB's answer below and adapting it, I would expect the following to do exactly that, but it throws an undefined error.

stringText = "something"
endChars = [",", ".", ";", " "]
textBlock = "This string may contain something;"

if any((stringText + end).lower() in textBlock.lower() for end in endChars):
    print("Match on " + end)

Expected output: Match on ;

Actual output NameError: name 'end' is not defined

UPDATE I have arrived at a suitable solution to this problem, at least for my requirements. It's not a one-liner, but it does the job. For completeness, shown below

for end in endChars:
    if stringText + end in textBlock:
        print("Match on " + end)
devklick
  • 2,000
  • 3
  • 30
  • 47
  • `re.search(r'something[,.; ]$',text,re.I)` – Mark Tolonen Dec 18 '17 at 22:58
  • I'd suggest changing the title (and maybe the example), cause this has confused most people into thinking you're looking for only at the end (hence all the answers with `.endswith()`). But I'm pretty sure that's not what you're going for. I've suggested an edit, (needs to be peer reviewed) but you might want to rephrase it yourself. – SCB Dec 18 '17 at 23:03
  • What if I change your example to use `stringText = "may"` or `stringText = "is"`? What results do you want for those? – Stefan Pochmann Dec 18 '17 at 23:23
  • @SCB, I'm happy with your change to the title of this post, it certainly makes more sense than mine. I feel the example is fairly clear though (albeit the example `if` statement is nonsense) - what I was looking for was put across, and the majority of suggestions (though not tried all), do what I was after. – devklick Dec 19 '17 at 18:10
  • @StefanPochmann, for the `stringText` values provided in your comment, I would expect `Match` to be printed for both. The reason being that 'is ' (including a trailing space) is present, as is 'may ' (including a trailing space). – devklick Dec 19 '17 at 18:13
  • Ok then the old title was indeed bad, since you didn't want any "Checking if a string ends"... – Stefan Pochmann Dec 19 '17 at 18:15
  • @StefanPochmann Yeah, checking if a string contains _another_ string, which ends in something... title was pretty misleading. Thanks – devklick Dec 19 '17 at 20:50

4 Answers4

3

You should perform the any() as the outmost operation (and in fact, you don't even need regex).

if any(stringText + end in textBlock for end in endChars):
    print("Match")

To perform case insensitive matching, just use the .lower() function on both sides:

if any((stringText + end).lower() in textBlock.lower() for end in endChars):
    print("Match")
SCB
  • 5,821
  • 1
  • 34
  • 43
  • This seems simple enough and looks like it should do the job, however can this be made case-insensitive? – devklick Dec 18 '17 at 22:56
  • Yeah, it could by converting everything to lowercase. I'll add an edit. – SCB Dec 18 '17 at 22:57
  • Using your answer is it possible to adapt this to display the item from the `endChars` array which was matched on? I've updated the original question with more information on this. – devklick Dec 19 '17 at 23:31
  • The reason you're getting that error you mention above is because the scope of `end` only exists inside the `any()` generator. By the time you get into the `if` statement, it's no longer there. Since this isn't what the original question asked, I'd suggest you open another question with your new requirements. – SCB Dec 19 '17 at 23:38
1

A non regex solution:

stringText = "something"
endChars = [",", ".", ";", " "]
textBlock = "This string may contain something;"
if any((stringText+i in textBlock for i in endChars):
   #condition met
   pass

Regex solution:

import re
if re.findall('|'.join('{}\{}'.format(stringText, i) for i in endChars), textBlock):
   #condition met
   pass
Ajax1234
  • 69,937
  • 8
  • 61
  • 102
0

A solution using any() and map built-ins:

stringText = "something"
endChars = [",", ".", ";", " "]
textBlock = "This string may contain something;"

if any(map(textBlock.endswith, [stringText, *endChars])):
    print("Match")
  • [stringText, *endChars] is the list of all possible endings.
  • map() maps each element of that list to the method textBlock.endswith()
  • any() returns True is any of the elements of map() is True
tpvasconcelos
  • 671
  • 7
  • 19
0
testBlock.endswith(tuple([stringText + endChar for endChar in endChars]))
David Taub
  • 734
  • 1
  • 7
  • 27