문제

나는 코드 부분을 차례로 전화 번호 링크로 이동 전화를 위한-나는 그것을 가지고 있지만 그것은 정말 기분이 더럽습니다.

import re
from string import digits

PHONE_RE = re.compile('([(]{0,1}[2-9]\d{2}[)]{0,1}[-_. ]{0,1}[2-9]\d{2}[-_. ]{0,1}\d{4})')

def numbers2links(s):
    result = ""
    last_match_index = 0
    for match in PHONE_RE.finditer(s):
          raw_number = match.group()
          number = ''.join(d for d in raw_number if d in digits)
          call = '<a href="tel:%s">%s</a>' % (number, raw_number)
          result += s[last_match_index:match.start()] + call
          last_match_index = match.end()
    result += s[last_match_index:]
    return result

>>> numbers2links("Ghost Busters at (555) 423-2368! How about this one: 555 456 7890! 555-456-7893 is where its at.")
'Ghost Busters at <a href="tel:5554232368">(555) 423-2368</a>! How about this one: <a href="tel:5554567890">555 456 7890</a>! <a href="tel:5554567893">555-456-7893</a> is where its at.'

어쨌든 내가할 수 있 재구성 또는 regex the regex 방법을 사용하고 이것을 만들기

업데이트

을 명확하게 질문을하지 않의 정확성에 대한 내 regex-나는 그것의 제한됩니다.신이 어떤 의견의 방법에 substiting 링크에 대한 전화 번호-어쨌든 내가 사용할 수 re.replace 나는 대신 문자열의 해커가?

도움이 되었습니까?

해결책

좋은 첫 번째 테이크 :) 나는이 버전이 조금 더 읽기 쉽다고 생각합니다 (그리고 아마도 십대가 조금 더 빠릅니다). 여기에 주목해야 할 주요 사항은 Re.sub. 우리를 불쾌한 경기 인덱스에서 멀리 떨어 뜨립니다 ...

import re

PHONE_RE = re.compile('([(]{0,1}[2-9]\d{2}[)]{0,1}[-_. ]{0,1}[2-9]\d{2}[-_.  ]{0,1}\d{4})')
NON_NUMERIC = re.compile('\D')

def numbers2links(s):

   def makelink(mo):
      raw_number = mo.group()
      number = NON_NUMERIC.sub("", raw_number)
      return '<a href="tel:%s">%s</a>' % (number, raw_number)

   return PHONE_RE.sub(makelink, s)


print numbers2links("Ghost Busters at (555) 423-2368! How about this one: 555 456 7890! 555-456-7893 is where its at.")

참고 : 제 연습에서, 나는 당신이 수천 번 사용하더라도 내가 사용하는 두 가지와 같은 간단한 정규 표현식을 사전 컴파일하는 데 많은 속도를 발견하지 못했습니다. RE 모듈에는 일종의 내부 캐싱이있을 수 있습니다. 소스를 읽고 확인하는 것을 귀찮게하지 않았습니다.

또한 각 캐릭터를 확인하여 그것이 있는지 확인하는 방법을 대체했습니다. string.digits 다른 것 re.sub() 내 버전이 더 읽기 쉽다고 생각하기 때문입니다.

다른 팁

REGEXP는 국제 표준이 아닌 특정 형식 만 구문 분석합니다. 한 국가로 자신을 제한하면 효과가있을 수 있습니다.

그렇지 않으면 국제 표준은입니다 ITU E.123 : "국가 및 국제 전화 번호, 이메일 주소 및 웹 주소에 대한 표기"

우선, 단일 정규 표현으로 전화 번호를 안정적으로 캡처하는 것은 불가능한 경향이 강한 것으로 악명이 높습니다. 모든 국가가 미국에서도 미국 에서처럼 좁은 "전화 번호"에 대한 정의를 가지고있는 것은 아닙니다. 북미 번호 매기기 계획에 관한 Wikipedia 기사):

  • A) 국가 코드 : 선택적 접두사 ( "1"또는 "+1"또는 "001")
    • ((00|\+)?1)?
  • b) 번호 매기기 계획 영역 코드 (NPA) : 1부터 시작할 수없고, 숫자 2는 9가 될 수 없습니다.
    • [2-9][0-8][0-9]
  • c) Exchange Code (NXX) : 1로 시작할 수없고 "11", 선택적 괄호로 끝날 수 없습니다.
    • \(?[2-9](00|[2-9]{2})\)?
  • d) 스테이션 코드 : 4 자리, 모두 0이 될 수는 없습니다 (나는 생각합니다)
    • (?!0{4})\d{4}
  • e) 선택적 확장이 따를 수 있습니다
    • ([x#-]\d+)?
  • s) 숫자의 일부는 공백, 대시, 점 (또는 그렇지 않음)으로 분리됩니다.
    • [. -]?

따라서 미국의 기본 정규식은 다음과 같습니다.

((00|\+)?1[. -]?)?\(?[2-9][0-8][0-9]\)?[. -]?[2-9](00|[2-9]{2})[. -]?(?!0{4})\d{4}([. -]?[x#-]\d+)?
| A       |S   |  |   B                | S   |   C             | S  |  D           | S  |  E      |

그리고 그것은 단지 미국의 상대적으로 사소한 번호 매기기 계획을위한 것이며, 그곳에서도 모든 미묘함을 다루는 것은 아닙니다. 신뢰할 수있게하려면 모든 예상 입력 언어에 대해 유사한 짐승을 개발해야합니다.

기능을 실제로 변경하지 않고 기존 정규식을 정리할 몇 가지 사항 :

{0,1}을?, [(]]와 함께 (, [)]로 대체하십시오. 또한 [2-9] BEA D를 만들 수도 있으므로 마지막 부분에 대해 해당 패턴을 D {3} 및 D {4}로 만들 수 있습니다. 나는 그것이 잘못된 긍정적 인 비율을 실제로 증가시킬 것이라고 의심합니다.

왜 다시 사용하여 다른 사람의 일-예를 들어, RegExpLib.com?

두 번째는 기억하는 다른 나라가 있습니다 게다가 미국,그리고 매우 그들 중 몇몇은 전화;-)는 것을 잊지 마십시오 우리 중에 소프트웨어 개발.

또한,이에 대한 표준 포맷의 전화 번호ITU's E.123.나의 기억 표준은 그것이 무엇인지에 대해 설명합하지 않는 경기와 잘 있습니다.

편집:혼합 G.123E.123.죄송합니다.소품 Bortzmeyer

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top