문자열에서 "두 번 나타나는 한 글자"찾기
RegEx를 사용하여 문자열에 두 번 나타나는 하나의 문자를 잡으려고합니다 (또는 더 나은 방법이 있습니까?). 예를 들어 내 문자열은 다음과 같습니다.
ugknbfddgicrmopn
출력은 다음과 같습니다.
dd
그러나 다음과 같은 것을 시도했습니다.
re.findall('[a-z]{2}', 'ugknbfddgicrmopn')
그러나이 경우 다음을 반환합니다.
['ug', 'kn', 'bf', 'dd', 'gi', 'cr', 'mo', 'pn'] # the except output is `['dd']`
또한 예상 출력을 얻는 방법이 있습니다.
>>> l = []
>>> tmp = None
>>> for i in 'ugknbfddgicrmopn':
... if tmp != i:
... tmp = i
... continue
... l.append(i*2)
...
...
>>> l
['dd']
>>>
하지만 너무 복잡합니다 ...
인 경우 'abbbcppq'
다음 만 포착하십시오.
abbbcppq
^^ ^^
따라서 출력은 다음과 같습니다.
['bb', 'pp']
그런 다음이면 두 번 'abbbbcppq'
잡습니다 bb
.
abbbbcppq
^^^^ ^^
따라서 출력은 다음과 같습니다.
['bb', 'bb', 'pp']
캡처 그룹 기반 정규식을 사용하고 정규식을 원시 문자열로 정의해야합니다.
>>> re.search(r'([a-z])\1', 'ugknbfddgicrmopn').group()
'dd'
>>> [i+i for i in re.findall(r'([a-z])\1', 'abbbbcppq')]
['bb', 'bb', 'pp']
또는
>>> [i[0] for i in re.findall(r'(([a-z])\2)', 'abbbbcppq')]
['bb', 'bb', 'pp']
그 참고 re.findall
여기서 첫번째 엘리먼트 및 제 소자로서 두 번째 그룹으로서 제 1 그룹과 일치하는 문자 튜플들의 목록을 반환한다. 우리의 경우 첫 번째 그룹 내의 문자로 충분하므로 언급했습니다 i[0]
.
Python 방식 zip
으로 목록 이해 내에서 함수 를 사용할 수 있습니다 .
>>> s = 'abbbcppq'
>>>
>>> [i+j for i,j in zip(s,s[1:]) if i==j]
['bb', 'bb', 'pp']
큰 문자열을 처리하는 경우 iter()
함수를 사용 하여 문자열을 반복자로 변환하고 itertols.tee()
두 개의 독립 반복자를 생성하는 데 사용할 수 있습니다. 그런 다음 next
두 번째 반복기 에서 함수를 호출 하여 첫 번째 항목을 사용하고 zip
클래스 호출을 사용할 수 있습니다 (Python 2.X에서 사용). itertools.izip()
반복자를 반환)이 반복자와 함께.
>>> from itertools import tee
>>> first = iter(s)
>>> second, first = tee(first)
>>> next(second)
'a'
>>> [i+j for i,j in zip(first,second) if i==j]
['bb', 'bb', 'pp']
RegEx
레시피를 사용한 벤치 마크 :
# ZIP
~ $ python -m timeit --setup "s='abbbcppq'" "[i+j for i,j in zip(s,s[1:]) if i==j]"
1000000 loops, best of 3: 1.56 usec per loop
# REGEX
~ $ python -m timeit --setup "s='abbbcppq';import re" "[i[0] for i in re.findall(r'(([a-z])\2)', 'abbbbcppq')]"
100000 loops, best of 3: 3.21 usec per loop
당신은 단지 한 쌍과 일치 할 경우 마지막 편집 후 주석에 언급 된 b
것처럼 문자열에 "abbbcppq"
사용할 수있는 finditer()
일치하는 객체의 반복자를 반환하고, 함께 결과 추출 group()
방법 :
>>> import re
>>>
>>> s = "abbbcppq"
>>> [item.group(0) for item in re.finditer(r'([a-z])\1',s,re.I)]
['bb', 'pp']
Note that re.I
is the IGNORECASE flag which makes the RegEx match the uppercase letters too.
Using back reference, it is very easy:
import re
p = re.compile(ur'([a-z])\1{1,}')
re.findall(p, u"ugknbfddgicrmopn")
#output: [u'd']
re.findall(p,"abbbcppq")
#output: ['b', 'p']
For more details, you can refer to a similar question in perl: Regular expression to match any character being repeated more than 10 times
It is pretty easy without regular expressions:
In [4]: [k for k, v in collections.Counter("abracadabra").items() if v==2]
Out[4]: ['b', 'r']
Maybe you can use the generator to achieve this
def adj(s):
last_c = None
for c in s:
if c == last_c:
yield c * 2
last_c = c
s = 'ugknbfddgicrmopn'
v = [x for x in adj(s)]
print(v)
# output: ['dd']
"or maybe there's some better ways"
Since regex is often misunderstood by the next developer to encounter your code (may even be you), And since simpler != shorter,
How about the following pseudo-code:
function findMultipleLetters(inputString) {
foreach (letter in inputString) {
dictionaryOfLettersOccurrance[letter]++;
if (dictionaryOfLettersOccurrance[letter] == 2) {
multipleLetters.add(letter);
}
}
return multipleLetters;
}
multipleLetters = findMultipleLetters("ugknbfddgicrmopn");
A1 = "abcdededdssffffccfxx"
print A1[1]
for i in range(len(A1)-1):
if A1[i+1] == A1[i]:
if not A1[i+1] == A1[i-1]:
print A1[i] *2
>>> l = ['ug', 'kn', 'bf', 'dd', 'gi', 'cr', 'mo', 'pn']
>>> import re
>>> newList = [item for item in l if re.search(r"([a-z]{1})\1", item)]
>>> newList
['dd']
ReferenceURL : https://stackoverflow.com/questions/34261346/find-one-letter-that-appears-twice-in-a-string
'IT박스' 카테고리의 다른 글
RedirectToAction에서 모델을 매개 변수로 전달할 수 있습니까? (0) | 2020.12.30 |
---|---|
모듈 파일에서 매크로를 어떻게 사용합니까? (0) | 2020.12.30 |
가져 오기 : JSON 오류 객체로 약속 거부 (0) | 2020.12.29 |
iOS에서 오디오 볼륨 레벨 및 볼륨 변경 알림을받는 방법은 무엇입니까? (0) | 2020.12.29 |
.Contains가 느린 이유는 무엇입니까? (0) | 2020.12.29 |