2016-06-29 5 views
2

주소를 정리 중입니다. 나는 특정 단어 (애비뉴, 애비뉴, 도로, 장소 등 기타 등등) 이후의 모든 것을 제거하려고합니다.분할 문자열은 여러 개의 가능한 제거기를 기반으로하지만 구분 기호 유지

나는 이런 식으로하고 있었는데, 나는 이것이 단어 앞에 모든 것을 돌려 줄 것이라고 믿는다. 즉 "1 번가"가 "1 번 우선"을 반환합니다.

어떻게 추가 할 수 있습니까 (또는 다르게합니까?) 패턴 단어를 포함하여 모든 것을 반환 할 수 있습니까?

patterns = ["ave", "avenue", "road", "street" etc etc etc] 
reduce(lambda s, pat: s.split(pat, 1)[0], patterns, string) 
+0

이 효율적 소리가 나지 않는다 구분 기호 단어를 다시 추가 할 때 알고 감소와 필터이다 , 당신은'patterns' 배열을 반복 할 수 있고,'id = s.split.index (patterns [i])'그리고 나서'string = s [: id]'를 마침내'return ''.join (string)'하지만 꽤 귀엽다. ficient imo. 아마도 이것을 최적화 할 수있을 것입니다. –

답변

1

이 몇 가지 방법이를 달성하기 위해.

patterns = ["ave", "avenue", "road", "street"] 
string = 'queen ave west' 
reduce(lambda s, pat: s[:s.find(pat)+len(pat)] if s.find(pat) > 0 else s, patterns, string) 

그러나 정규 표현식의 사용을 통해 어쩌면 더 나은 해결 방법 : reduce 여기 significene이있는 경우,이 하나 lambda 내 대답을 유지하는 방법입니다.

여러 주소로이를 적용하는 경우
import re 
patterns = ["ave", "avenue", "road", "street"] 
regex = r'(.*)(' + '|'.join(patterns) + r')(.*)' 
string = 'queen ave west' 
re.sub(regex, r'\1\2', string) 

, 당신은 컴파일하여 코드를 최적화 할 수 있습니다 : 이것은 하나의 정규 표현식으로 가능 "패턴"을 모두 결합하여 파이썬의 정규 표현식 엔진을 통해 한 번에 모든 일을 실행 정규 표현식은 먼저 당신이 정리하려는 각 주소에 컴파일 된 정규식을 사용하여 :

import re 

patterns = ["ave", "avenue", "road", "street"] 
regex = re.compile(r'(.*)(' + '|'.join(patterns) + r')(.*)') 
strings = ['queen ave west', 'should stay the same'] 
sanitized_strings = (regex.sub(r'\1\2', string) for string in strings) 

이제 sanitized_strings 문자열의 버전을 청소 포함되어 있습니다. for 루프를 사용하여 sanitized_strings을 반복하고 인쇄하거나 필요한 작업을 수행 할 수 있습니다. patterns에있는 단어가 없으면 전체 문자열이 첫 번째 그룹과 일치합니다. 따라서 단어가 없으면 요청한 것처럼 문자열을 변경하지 않습니다.

나는 당신이 찾고있는 것과 정확히 일치하지는 않습니다. 예를 들어, 정말로 'queen ave'를 'queen ave west'로 반환하고 싶습니까? 패턴 중 하나가 거리의 이름 일 때 패턴을 'st'로 또는 예를 들어 토론토에서 패턴을 나타내는 경우 매우 가능성이 높습니다. '애비뉴로드'라고 불렀습니다. 그 질문에 대한 답은 당신이 성취하고자하는 것에 달려 있습니다.

+0

두 번째 솔루션을 루프로 변환하면 주소에서이 코드를 시도 할 수 있고 실패 할 경우 어떻게됩니까? 이전에 주소를 그대로 유지 하시겠습니까? – Harrison

+0

@hleggs는 예제와 자세한 설명으로 답변을 업데이트했습니다. 그것은 이미 당신이 원하는 것을 수행합니다. 단어가 없다면 문자열을 똑같이 유지할 것입니다. – hashemi

+0

정말 고마워요! 완벽한 구현! – Harrison

2

나는 이것이 당신이 원하는 것이라고 생각합니다.

pattern = ['ave', 'street', 'road'] 
address = 'Imaginary ave, Fantasy Island' 

for i in pattern: 
    if i in address: 
     print address[:address.find(i) + len(i)] 

또는 주소

print [address[:address.find(i) + len(i)] for i in pattern if i in address] 
+1

두 번째 예제에서는 끝에'string' 대신'address'가 있어야합니다. –

+0

맨 먼저 가장 빠른 답변을 보내 주셔서 감사드립니다. 좀 더 구체적으로 설명해 드리면이 구현이 효과가 있는지 알려 주시기 바랍니다. 나는 파일에서 주소 1을 읽으며 다른 것들을하기 전에 주소를 포맷해야한다. 그래서 각 줄마다 당신은 당신의 대답에 포함 된 그 중첩 된 루프를 사용할 것입니까? @DeanFenster 고맙다는 것에 감사합니다. – Harrison

+0

. Fixed – af3ld

0

이, 본인은으로, 그러나 문자열 index() 방법 (사용되는 문자열의 특정 하위 문자열 검색을 위해 일 것입니다 목록이있는 경우 사용자는이 문제를 해결할 수있는 여러 가지 방법이 있음을 지적 했으므로 try/except 블록이있는 이유입니다. 하위 문자열이 없으면 index() 메서드는 오류를 반환합니다.

def strip_address(string): 
    patterns = ["ave", "road", "street"] 
    final_address = '' 

    for pattern in patterns: 
     try: 
      if not string.index(pattern): continue 

      # The tail-index of the pattern in the string 
      last_index = len(pattern) + string.index(pattern) 

      final_address = string[:last_index] # parsed address 
      return final_address 

     except ValueError: 
      pass 

는 테스트 :

string = "1 first street 213322" 
> '1 first street' 

string1 = "1023 sunset road Extra Text here" 
> '1023 sunset road' 

string2 = "23 applewood ave Apt.1241" 
> '23 applewood ave' 
+0

나는 그 if 문을 뒤집어서 더 많은 코드를 들여 쓰기보다는'continue'하게 만들었습니다. – Alexander

0

이 컴팩트 한 방법

print reduce (lambda s,x : str(s.split(x)[0]) if (str(s.split(x)[0]) == s) else str(s.split(x)[0]) + x,patterns) 

전체 예제를 사용할 수 있습니다

patterns = ["ave", "ave", "road" ] 
string = "1 first avenue" 
patterns.insert(0,string) 
print reduce (lambda s,x : str(s.split(x)[0]) if (str(s.split(x)[0]) == s) else str(s.split(x)[0]) + x,patterns) 

생각은 우리가

관련 문제