Use of pipe operator to search for substring in string

current scenario -
1)

('c' or 'a') in 'ab'

gives,

False

as ('c' or 'a') evaluates to 'c'

  1. the substring check could be obtained, but need to write it using any builtin
any([(i in 'ab') for i in ('c', 'a')])

gives,

True
  1. in a match case statement, one could check for exact match of a string,
x = 'ab'
match x:
  case 'ab' | 'c':
    print(1)

gives 1

but this pipe operator does not work for strings outside of match case statement.

expected scenario -

  1. pipe operator works for strings to check for substring in string, so,
('c' | 'a') in 'ab'

gives,

True

I have often found a need to test substring matching for multiple candidates. I don’t think the proposed syntax is the best solution, but I think there’s something there.


Not related to the proposal, there’s an optimisation to your second example: skipping the list creation

any((i in 'ab') for i in ('c', 'a'))

For large iterables (('c', 'a') in this example), this means both not constructing and storing a large list (of boolean values), but also ending the iteration on the first true value found.

Also it is not clear what do you propose to be the result of this sub-expression in your example:

Should it be a special object with a special treatment of the in operator? Can it be useful for something else?

yes that is a bit confusing, one solution is to make it a new object type, just like there is list_iterator, set_iterator, maybe ('c' | 'a') could return an object of type str_lookup.

I am investigating if it could be useful in some other place apart from the in scenario, but in my opinion, the substring search on its own is a pretty common use case in support of this change.

alongside one another way to achieve this is by using,

import re
if re.search('c|a', 'ab'):
  print(1)

where again the pipe operator is used to search the presence of any of these strings inside of re.search.
I would prefer to achieve the same without using the regex module.

there is one more way to achieve this by using a match-case statement and changing the way __eq__ works for a string,

class MatchString(str):
  def __eq__(self, other):
    return other in self

x = MatchString('abcdef')

match x:
  case 'a' | 'b':
    print(1)

gives, 1 as output