HTML 엔터티 디코딩 방법 (예 : & quot; 또는 & # 39;)


11

최근에 HTML 엔터티를 디코딩하는 문제가 발생했습니다. 다음 두 문자열이 있습니다 ( 이름과 번호가 지정된 두 가지 인코딩 방법이 사용되는 방법에 유의하십시오 ).

The old "how to fold xml" question
Babel doesn't wrap results in verbatim

그리고 그것들을

The old "how to fold xml" question
Babel doesn't wrap results in verbatim

주변을 둘러 보면서 SO에 대한이 오래된 질문 을 발견 했지만 (현재 내가하고있는 일) Emacs 가이 작업을 수행 할 기본 방법이 없다고 거부합니다. 메일 클라이언트와 피드 리더는 말할 것도없고, 적어도 2 개의 웹 브라우저가 내장되어 있습니다.

HTML 엔터티를 디코딩하는 기본 제공 방법이 없습니까?
첫 번째 예제에서 문자열을 가져와 두 번째 예제에서 문자열을 반환하는 함수를 찾고 있습니다.


아무것도 없다면 DTD를 구문 분석하고 문서에서 엔티티를 확인할 수 있기 때문에 nxml 코드에 있어야합니다.
wasamasa

libxml-parse-html-region물론이 작업을 수행하지만 HTML 태그도 구문 분석한다는 점에서 원하는 것보다 더 많은 작업을 수행 할 수 있습니다 ... (그리고 모든 Emacs가 LibXML 지원으로 빌드되는 것은 아닙니다.)
Jon O.

답변:


7

이맥스에서 순수 Elisp XML 파서 포함 xml.el그, xml-parse-string그것을 문서화되지 않은 내부 함수처럼 조금 보이지만, 함수 작업을 수행합니다. 문자열을 XML 조각으로 취급하여 제대로 처리되지 않는 HTML 전용 엔터티가 있는지 확실하지 않습니다.

이 래퍼 함수는 입력 문자열에서 후행 태그를 생략하지만 더 엄격하게 만들 수 있습니다.

(defun decode-entities (html)
  (with-temp-buffer
    (save-excursion (insert html))
    (xml-parse-string)))

(decode-entities "The old "how to fold xml" question")
;; => "The old \"how to fold xml\" question"

(decode-entities "doesn't")
;; => "doesn't"

(decode-entities "string with trailing tag: <tag/>")
;; => "string with trailing tag: "

LibXML을 지원하는 Emacs에서 또 다른 약간의 해킹 방법은 래퍼를 작성하는 것 libxml-html-parse-region입니다. LibXML 구문 분석기는 해당 인수가 완전한 HTML 문서라고 가정하므로 랩퍼 함수는를 사용하여 리턴 된 문서 구조에서 구문 분석 된 문자 데이터를 추출해야합니다 pcase. HTML 태그가 포함 된 문자열을 디코딩하려고하면 오류가 발생합니다.

(defun decode-entities/libxml (html)
  (with-temp-buffer
    (insert html)
    (let ((document
           (libxml-parse-html-region (point-min) (point-max))))
      (pcase document
        (`(html nil
                (body nil
                      (p nil
                         ,(and (pred stringp)
                               content))))
          content)
        (_ (error "Unexpected parse result: %S" document))))))

결과 :

(decode-entities/libxml "The old &quot;how to fold xml&quot; question")
     ; => "The old \"how to fold xml\" question"
(decode-entities/libxml "doesn&#39;t") ; => "doesn't"

(decode-entities/libxml "<html>")              ; produces an error

문서 조각을 완전한 문서로 구문 분석하여 주변 조각을 즉시 제거하기 위해 문서 조각을 해독하는 것은 약간 뒤 떨어진 것처럼 보입니다. 반면에 LibXML을 사용하면 빠르고 정확한 결과를 얻을 수 있습니다.


죄송합니다, 귀하의 XML 편집을 보지 못했습니다. 굉장해 보인다.
Malabarba

감사합니다-더 간단한 xml.el솔루션을 먼저 만들기 위해 답을 편집했습니다 .
Jon O.

@Malabarba Jon O. 와 동일한 엔티티 디코딩을 수행하는 lisp/xml.el함수가 항상 포함되어 있습니다. 그러나 후행 태그는 생략하지 않습니다. xml-substitute-specialdecode-entities
Basil

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.