다른 문자열에 여러 문자열이 있는지 확인


378

배열의 문자열이 다른 문자열에 있는지 어떻게 확인할 수 있습니까?

처럼:

a = ['a', 'b', 'c']
str = "a123"
if a in str:
  print "some of the strings found in str"
else:
  print "no strings found in str"

그 코드는 작동하지 않습니다. 달성하려는 것을 보여주기 위해서입니다.


5
나는 퍼포먼스 측면에서 컴파일 된 정규 표현식과 비교할 때 (아직도) 문자열의 크기와 검색 할 "니들"의 수에 비해 (아직) 대답이 없다는 것에 놀랐습니다.
Pat

3
@ 팻 나는 놀라지 않습니다. 문제는 성능에 관한 것이 아닙니다. 오늘날 대부분의 프로그래머는이를 수행하고 가독성을 높이기 위해 더 많은 노력을 기울입니다. 성과 질문은 유효하지만 다른 질문입니다.
guettli

13
str을 변수로 사용하는 것은 혼란스럽고 예약어이므로 예기치 않은 동작이 발생할 수 있습니다. 링크를 참조 하십시오 .
Clever Guy

정규식 [abc]도 완벽하게 작동하며 테스트 할 후보가 두 명 이상인 경우 더 빠릅니다. 그러나 문자열이 임의적이며 정규 표현식을 구성하기 위해 미리 알지 못하면 any(x in str for x in a)접근 방식 을 사용해야합니다 .
smci

@CleverGuy 예약어가 아니더라도 맞습니다. 그렇지 않으면 할당 할 수 없습니다. 내장되어 있습니다.
wjandrea

답변:


717

당신은 사용할 수 있습니다 any:

a_string = "A string is more than its parts!"
matches = ["more", "wholesome", "milk"]

if any(x in a_string for x in matches):

마찬가지로 목록의 모든 문자열 이 있는지 확인 하려면 all대신을 사용하십시오 any.


11
any ()는 iterable을 사용합니다. 사용중인 Python 버전을 확실하지 않지만 2.6에서는 any ()에 대한 인수 주위에 []를 넣어야합니다. 이해력이 iterable을 반환하도록 any ([x in a str for x])). 그러나 이후 버전의 Python은 이미이 작업을 수행합니다.
emispowder

7
@Mark Byers : 늦게 언급해서 죄송하지만 발견 된 문자열을 인쇄하는 방법이 있습니까? 어떻게 하시겠습니까? 감사합니다.
Shankar Kumar

3
a가 목록이고 str이 일치하는 것이라면 x가 무엇인지 이해하지 못합니다. 파이썬 초보자 ftw. :)
빨간색

2
@red : for x in a"목록의 각 요소"와 같이 읽을 수 있습니다 . 이후 a문자열리스트이고, x그리스트의 소자이며, x문자열 ( 'A', 원래의 실시 예에서 'B', 'C'중 하나)이다
사용자

6
@emispowder Python 2.6.9에서와 같이 작동합니다.
MPlanchard

67

any()원하는 모든 것이 True또는 False인 경우 가장 좋은 방법 이지만, 어떤 문자열 / 문자열이 일치하는지 구체적으로 알고 싶다면 몇 가지를 사용할 수 있습니다.

첫 번째 일치를 원할 경우 ( False기본값) :

match = next((x for x in a if x in str), False)

모든 경기 (중복 포함)를 얻으려면 :

matches = [x for x in a if x in str]

중복되지 않은 모든 일치 항목을 얻으려면 (순서 무시) :

matches = {x for x in a if x in str}

중복되지 않은 모든 일치 항목을 올바른 순서로 얻으려면 다음을 수행하십시오.

matches = []
for x in a:
    if x in str and x not in matches:
        matches.append(x)

마지막 경기도 예를 추가해주세요
Oleg Kokorin

@ OlegKokorin : 일치하는 문자열 목록을 찾은 순서와 동일한 순서로 생성하지만 두 개가 동일한 경우 첫 번째 문자열 만 유지합니다.
zondo

목록을 사용하는 OrderedDict것이 아마도 성능이 더 뛰어납니다. "목록에서 중복 제거"
wjandrea

44

줄 이 길어 a지거나 str길어질 경우주의해야합니다 . 간단한 솔루션은 O (S * (A ^ 2))를 취합니다. 여기서 S길이는 strA이고에있는 모든 문자열 의 길이의 합입니다 a. 더 빠른 솔루션을 위해 선형 시간 O (S + A)로 실행되는 문자열 일치에 대한 Aho-Corasick 알고리즘을 살펴보십시오 .


Aho-Corasick은 접두사 대신 하위 문자열을 찾을 수 있습니까?
RetroCode

1
일부 파이썬 Aho-Corasick 라이브러리가 여기있습니다
vorpal

23

다음과 regex같이 다양성을 추가하십시오 .

import re

if any(re.findall(r'a|b|c', str, re.IGNORECASE)):
    print 'possible matches thanks to regex'
else:
    print 'no matches'

또는 목록이 너무 긴 경우- any(re.findall(r'|'.join(a), str, re.IGNORECASE))


1
이것은 주어진 질문의 유스 케이스에 적용됩니다. 정규식 구문에 대한 인용을 수행해야하므로 검색 (또는 *이것이 실패하면.
guettli

2
로 필요한 경우 이스케이프 처리 할 수 ​​있습니다 '|'.join(map(re.escape, strings_to_match)). 당신은 아마 sould re.compile('|'.join(...))뿐만 아니라.
Artyer

12

a의 요소를 반복해야합니다.

a = ['a', 'b', 'c']
str = "a123"
found_a_string = False
for item in a:    
    if item in str:
        found_a_string = True

if found_a_string:
    print "found a match"
else:
    print "no match found"

2
네, 그렇게하는 방법을 알고 있었지만 Marks 답변과 비교하면 끔찍한 코드입니다.
jahmax

10
마크의 코드를 이해 한 경우에만. 당신이 겪고있는 문제는 배열의 요소를 검사하지 않았다는 것입니다. 코드에 문제가있는 것의 본질을 숨길 수있는 원하는 간결하고 비현실적인 방법이 많이 있습니다.
Seamus Campbell

9
'끔찍한 코드'일 수도 있지만 정확히 any () 가하는 것 입니다. 또한 이것은 일치하는 실제 문자열을 제공하는 반면 any ()는 일치하는 것을 알려줍니다.
alldayremix

4

jbernadas는 복잡성을 줄이기 위해 이미 Aho-Corasick-Algorithm 을 언급했습니다 .

다음은 파이썬에서 사용하는 한 가지 방법입니다.

  1. 여기 에서 aho_corasick.py를 다운로드 하십시오

  2. 기본 Python 파일과 동일한 디렉토리에 넣고 이름을 지정하십시오. aho_corasick.py

  3. 다음 코드를 사용하여 알고리즘을 시도하십시오.

    from aho_corasick import aho_corasick #(string, keywords)
    
    print(aho_corasick(string, ["keyword1", "keyword2"]))

검색은 대소 문자를 구분합니다.


3
a = ['a', 'b', 'c']
str =  "a123"

a_match = [True for match in a if match in str]

if True in a_match:
  print "some of the strings found in str"
else:
  print "no strings found in str"

1

그것은 당신이 같은 하나의 문자를 확인하고 싶은 경우 (단일 단어 A, E를, 등등 승) 가정 상황에 따라 달라집니다 에이 충분하다

original_word ="hackerearcth"
for 'h' in original_word:
      print("YES")

original_word 중 문자를 확인하려면 다음을 사용하십시오.

if any(your_required in yourinput for your_required in original_word ):

해당 original_word에 원하는 모든 입력을 원하면 모든 것을 간단하게 사용하십시오.

original_word = ['h', 'a', 'c', 'k', 'e', 'r', 'e', 'a', 'r', 't', 'h']
yourinput = str(input()).lower()
if all(requested_word in yourinput for requested_word in original_word):
    print("yes")

당신의 입력은 무엇입니까? 두 가지를 인식 할 수 있습니다 : 내가 찾고있는 문장. 내가 찾고있는 단어의 배열. 그러나 세 가지 변수를 설명하면 세 번째 변수를 얻을 수 없습니다.
mayid

1

String에서 모든 목록 요소를 사용 가능하게 만드는 방법에 대한 추가 정보

a = ['a', 'b', 'c']
str = "a123" 
list(filter(lambda x:  x in str, a))

1

놀랍게도 빠른 접근 방식은 다음을 사용하는 것입니다 set.

a = ['a', 'b', 'c']
str = "a123"
if set(a) & set(str):
    print("some of the strings found in str")
else:
    print("no strings found in str")

a여러 문자 값을 포함하지 않는 경우 작동 합니다 (이 경우 위에any 나열된 대로 사용 ). 그렇다면 a문자열 로 지정 하는 것이 더 간단합니다 a = 'abc'.


0
flog = open('test.txt', 'r')
flogLines = flog.readlines()
strlist = ['SUCCESS', 'Done','SUCCESSFUL']
res = False
for line in flogLines:
     for fstr in strlist:
         if line.find(fstr) != -1:
            print('found') 
            res = True


if res:
    print('res true')
else: 
    print('res false')

출력 예 이미지


0

나는 이런 종류의 기능을 속도에 사용할 것이다.

def check_string(string, substring_list):
    for substring in substring_list:
        if substring in string:
            return True
    return False

0
data = "firstName and favoriteFood"
mandatory_fields = ['firstName', 'lastName', 'age']


# for each
for field in mandatory_fields:
    if field not in data:
        print("Error, missing req field {0}".format(field));

# still fine, multiple if statements
if ('firstName' not in data or 
    'lastName' not in data or
    'age' not in data):
    print("Error, missing a req field");

# not very readable, list comprehension
missing_fields = [x for x in mandatory_fields if x not in data]
if (len(missing_fields)>0):
    print("Error, missing fields {0}".format(", ".join(missing_fields)));
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.