문자열에 목록의 요소가 포함되어 있는지 확인합니다.
다음 코드 블록의 경우:
For I = 0 To listOfStrings.Count - 1
If myString.Contains(lstOfStrings.Item(I)) Then
Return True
End If
Next
Return False
출력은 다음과 같습니다.
사례 1:
myString: C:\Files\myfile.doc
listOfString: C:\Files\, C:\Files2\
Result: True
사례 2:
myString: C:\Files3\myfile.doc
listOfString: C:\Files\, C:\Files2\
Result: False
목록(listOfStrings)은 여러 항목(최소 20개)을 포함할 수 있으며 수천 개의 문자열(myString과 같은)에 대해 확인해야 합니다.
이 코드를 더 효율적으로 작성할 수 있는 방법이 있습니까?
LINQ와 C#을 사용하는 경우(요즘은 VB를 잘 모릅니다.
bool b = listOfStrings.Any(s=>myString.Contains(s));
또는 (더 빠르고 더 효율적이지만 분명 덜 명확함):
bool b = listOfStrings.Any(myString.Contains);
만약 당신이 평등을 테스트하고 있다면, 그것은 볼 가치가 있을 것입니다.HashSet
등입니다. 그러나 이것은 조각으로 나누고 복잡성 순서를 추가하지 않는 한 부분 일치에는 도움이 되지 않습니다.
update:로 "StartsWith"를한다면, 할 수 . update: 만약당신정를이말로면한 "StartsWith"의미다당다신니은, 그을목고정배배열로렬하치수할있록다사니합나용습서리고▁update▁update:; :▁and▁;▁if다▁list니▁sort사합나▁array용start서,▁then▁you▁"리그고"▁then▁an▁it▁mean▁use만▁really▁you▁could;다니있▁the▁into▁place습start수약s치할열렬배를하Array.BinarySearch
각 항목 찾기 - 전체 또는 부분 일치 여부를 조회하여 확인합니다.
당신이 당신의 끈을 구성할 때는 이렇게 되어야 합니다.
bool inact = new string[] { "SUSPENDARE", "DIZOLVARE" }.Any(s=>stare.Contains(s));
저는 마크의 답변이 마음에 들었지만 CaSe InSenSiTiVe가 되기 위해서 Contains 매칭이 필요했습니다.
이것이 해결책이었습니다.
bool b = listOfStrings.Any(s => myString.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0))
이전의 유사한 질문 "많은 비교 가능한 목록에 대해 기존 문자열을 테스트하는 가장 좋은 방법"에서 많은 제안이 있었습니다.
Regex로 충분할 수 있습니다. 모든 서브스트링의이며 OR "은모든후서연입며결이의은다링식트니스브보▁or은", 또는 "입▁"다니▁the,며▁beion▁express"로 됩니다.|
그들 사이의 연산자.물론 표현식을 작성할 때 이스케이프되지 않은 문자를 주의해야 하거나 복잡성이나 크기 제한으로 인해 컴파일에 실패해야 합니다.
이를 위한 또 다른 방법은 모든 후보 하위 문자열을 나타내는 트라이 데이터 구조를 구성하는 것입니다(이것은 정규식 매칭기가 수행하는 것을 다소 복제할 수 있습니다).테스트 문자열의 각 문자를 단계적으로 통과할 때 트리의 루트에 대한 새 포인터를 만들고 기존 포인터가 있는 경우 해당 자식 포인터로 이동합니다.어떤 포인터가 잎에 닿으면 일치하는 것을 얻을 수 있습니다.
오래된 질문.하지만 그 이후로VB.NET
원래 요구 사항이었습니다.허용된 답변의 동일한 값 사용:
listOfStrings.Any(Function(s) myString.Contains(s))
목록에 있는 항목이 (긴) 문자열에 있는지 확인해야 했기 때문에 다음과 같은 항목을 선택했습니다.
listOfStrings.Any(x => myString.ToUpper().Contains(x.ToUpper()));
또는 vb.net 에서:
listOfStrings.Any(Function(x) myString.ToUpper().Contains(x.ToUpper()))
패턴에 따라 Contains 대신 StartsWith를 사용하는 것으로 변경할 수 있습니다.첫 번째 불일치를 찾을 때마다 모든 문자 위치에서 검색을 다시 시작하지 않고 첫 번째 불일치를 찾을 때까지 각 문자열을 반복해야 합니다.
또한 패턴에 따라 myString 경로의 첫 번째 부분을 추출한 다음 비교를 반대로 할 수 있습니다. 문자열 목록에서 myString의 시작 경로를 찾는 것이 아니라 문자열 목록에서 myString의 시작 경로를 찾는 것입니다.
string[] pathComponents = myString.Split( Path.DirectorySeparatorChar );
string startPath = pathComponents[0] + Path.DirectorySeparatorChar;
return listOfStrings.Contains( startPath );
편집: 변경할 수 있으므로 @Marc Gravell이 언급한 해시셋 아이디어를 사용하는 것이 훨씬 빠를 것입니다.Contains
로.ContainsKey
조회는 O(N) 대신 O(1)입니다.경로가 정확히 일치하는지 확인해야 합니다.이것은 @Marc Gravell과 같은 일반적인 해결책이 아니라 사용자의 예에 맞게 조정된 것입니다.
C# 예를 들어 죄송합니다.저는 VB로 번역할 만큼 충분한 커피를 마시지 못했습니다.
속도를 테스트해 보셨습니까?
예: 샘플 데이터 세트를 생성하고 프로파일링했습니까?당신이 생각하는 것만큼 나쁘지 않을 수도 있습니다.
이것은 또한 여러분이 별도의 실에 산란하여 속도의 환상을 줄 수 있는 것일 수 있습니다!
myList.Any(myString.Contains);
의 단점은Contains
방법은 문자열을 비교할 때 종종 중요한 비교 유형을 지정할 수 없다는 것입니다.그것은 항상 문화와 대소문자를 구분합니다.그래서 저는 WhoIsRich의 답은 가치가 있다고 생각합니다. 저는 단지 더 간단한 대안을 보여주고 싶습니다.
listOfStrings.Any(s => s.Equals(myString, StringComparison.OrdinalIgnoreCase))
속도가 중요한 경우 패턴 집합에 대한 Aho-Corasick 알고리즘을 찾는 것이 좋습니다.
오류 링크가 있는 시도입니다. 즉, 복잡도는 O(n+m+k)입니다. 여기서 n은 입력 텍스트의 길이, m은 패턴의 누적 길이 및 k 일치 수입니다.첫 번째 일치 항목이 발견된 후 종료되도록 알고리즘을 수정하면 됩니다.
약간의 변화, 저는 문자열에 전체 단어와 대소문자를 구분하지 않는 것이 있는지 확인해야 했습니다.
myString.Split(' ', StringSplitOptions.RemoveEmptyEntries).Intersect(listOfStrings).Any())
대소문자를 구분하지 않는 경우myString
그리고.listOfStrings
대문자로 변환되었습니다.
언급URL : https://stackoverflow.com/questions/500925/check-if-a-string-contains-an-element-from-a-list-of-strings
'programing' 카테고리의 다른 글
gitc fatal: 불량 객체 refs/remote/origin/HEAD 오류를 처리하는 방법? (0) | 2023.05.29 |
---|---|
bash if/else 문 안에서 파일 grep 비교를 사용하려면 어떻게 해야 합니까? (0) | 2023.05.29 |
Xcode의 기본 헤더 주석 라이센스 변경 (0) | 2023.05.29 |
node.js에 폴더의 모든 파일이 필요합니까? (0) | 2023.05.29 |
판다 데이터 프레임의 특정 행을 인쇄하는 방법은 무엇입니까? (0) | 2023.05.29 |