2009-12-08 6 views
2
에서 정규 표현식 및 역 참조를 사용하여 문자열을 교체

나는 라텍스을 HTML로 변환하고,이 변경하려면 노력하고있어Clojure의

baz\footnote{www.foo.com/bar} 

내가 좋아하는 것을에 텍스트 덩어리를 가져 오는 Clojure 함수를 생성하고 주어진 단락에 존재하는만큼의 일치 항목을 대체합니다.

"^Bfootnote{^A}" 

나는 또한 정규 표현식을 사용하여 기능을 대체 가지고있는, clojure.contrib.str-utils2을 검토 한 결과,하지만하지 않는 것 : 나는

(.replaceAll 
    "<a href=\"foo.com\">baz</a>" 
    "<a.*href=\"(.*)\">(.*)</a>" 
    "\2\\footnote{\1}") 

을 시도했지만 그 반환

역 참조를 처리합니다. 내가 놓친 게 있니? 이 잘못된 방향으로 가고 있습니까? 어떤 도움을 주셔서 감사합니다.

+0

불행한 regexes와 HTML 선택에 대한 아래 답변의 언급과 관련하여, 나는 이것이 일회용 프로그램이라고 말하면서 용서할 만하다. 프로그래밍 방식으로 나를 일찍 생성했습니다.저는 XML 솔루션이 지속 가능성과 재사용 성을위한 올바른 방법이라고 생각합니다. 그러나이 시점에서 나는 그것을 함께 해킹하려고하고 있습니다. –

답변

4

(You should not parse HTML with a regex...)

두 가지 :

  1. 자바 $1 사용 $2은하지 \1, \2을 그룹을 캡처를 참조하십시오.

  2. 대체 텍스트에 더 많은 백 슬래시가 필요합니다. 백 슬래시의 첫 번째 레벨은 리터럴 문자열이기 때문에 Clojure 독자가 사용합니다. 두 번째 수준의 백 슬래시는 정규식에서 사용합니다. 불행히도 Clojure에는 "원시"문자열 리터럴 (아직?)에 대한 일반 구문이 없습니다. Clojure 리터럴 정규식 구문 #""은 일부 백 슬래시를 절약하기 위해 일부 마법을 사용하지만 일반 문자열에는 그 마법이 없습니다.

그래서 :

user> (require '(clojure.contrib [str-utils2 :as s])) 
nil 
user> (s/replace "<a href=\"www.foo.com/bar\">baz</a>" 
       #"<a.*href=\"(.*)\">(.*)</a>" 
       (fn [[_ url txt]] 
        (str txt "\\\\footnote{" url "}"))) 
"baz\\footnote{www.foo.com/bar}" 

"\2" 그것이 ^B로 표시되는 이유입니다 제어 문자 (ASCII 문자 2)입니다 :

user> (.replaceAll "<a href=\"www.foo.com/bar\">baz</a>" 
        "<a.*href=\"(.*)\">(.*)</a>" 
        "$2\\\\footnote{$1}") 
"baz\\footnote{www.foo.com/bar}" 

당신은 이런 식으로 할 수도 있습니다. (char 2)과 거의 같습니다.

+0

s/replace 옵션을 통해 .replaceAll을 선택해야하는 이유가 있습니까? 그들은 둘 다 작동해야 하나, 더 높은 처리 요구 사항을 가지고 있습니까, 아니면 하나 더 관용적 인 Clojure입니까? 동등한 기능성을 감안할 때 가장 좋은 방법은 무엇입니까? –

+0

'clojure.contrib.str-utils2/replace'는 더 많은 작업을 수행합니다 (세 번째 인수로 fn을 전달할 수 있음). 하지만 프로젝트에 대한 의존성이 더 커졌습니다. 둘 중 하나를 사용하는 것은 관용적이며 Java 호출을 자제 할 필요가 없습니다. 개인적으로 나는 대부분의 일에'str-utils'를 사용합니다. –

1

그리고 정말로 spiffy가되고 싶다면 clojure.xml로 가십시오. 원하는대로 수정할 수있는 구조의 트리를 반환합니다. 귀하의 위의 예는 다음과 같습니다 쉽게 원하는 형태로 다시 직렬화 할 수

["bar" {:footnote "www.foo.com/bar"}]

:

{:tag :a :attrs {:href "www.foo.com/bar"} :content ["bar"]}

이 쉽게 같은로 번역 할 수 있습니다. 그리고 가장 좋은 부분은 유지 보수 할 수없는 정규 표현식이 아닙니다. :) 물론 YMMV .....