Don't parse HTML with regexen!를 진심으로, 그것은 일반적인 경우에 사실상 불가능하다. 그리고 실제로, 당신은 regexen으로 원하는 것을 할 수 없습니다. 균등 중첩 된 쌍의 괄호가 일치하는 것과 동일한 문제입니다. 단, 중첩 된 <title>
/</title>
쌍과 일치시키고 자하는 것은 일반 언어가 아닙니다.
(편집 1 :. 당신이 DOM에 접근하지 않았다고 본 이후 내가 내 대답을 수정했다, 나는 원래 무엇을했다, 아래 참조)에 따라서
, 왜 필요합니까 이것을하기 위해? 아마도 더 좋은 방법이있을 것입니다. 이 태그가 붙은 자바 스크립트이지만 대답에는 언급하지 않습니다. 자바 스크립트를 사용하지 않는다면 아마도 HTML 파서를 사용할 수있을 것입니다. 아마도 더 나은 선택 일 것입니다. 자바 스크립트를 사용하고 있다면 여전히 있을지 모르지만 저는 자바 스크립트 전문가가 아닙니다.
이제 여러 개의 또는 중첩 된 title
태그가있는 것은 실제로 유효한 HTML이 아니므로 은에 대해 걱정할 필요가 없습니다. 이것이 사실이라면 더 많은 가정을 할 수 있다면 실제로 작동 할 수있는 유스 케이스를 만들 수 있습니다. 예를 들면 : 코멘트가없고, CDATA
블럭이 없습니다. (네스트가 없기 때문에 이것을 처리 할 수는 있겠지만) 그러나 나는 잊고있는 엣지 경우가있을 수 있습니다! 또한 Safari와 Firefox는 세 번째 케이스를 중첩 된 제목 태그로 처리하지 않고 리터럴 문자열 Title of the document <title> Continuing title
을 포함하는 하나의 제목 태그로 보았습니다. 따라서, 당신이 그 케이스를 무시할 수 있다면, 이 작동 할 수있는 깨지기 쉬운 정규식 세트를 함께 해킹하는 것이 가능할 수 있습니다. 아마 (가볍게 시험 한!이 같은) 뭔가 :
// Edit 2: Made this function case-insensitive where it needed to be.
// Edit 3: Used substring() instead of replace() to remove the extraneous
// title tags and fixed the "not matching" case.
function getTitle(html) {
return (html.replace(/<!\[CDATA\[(.+?)\]\]>/g
, function (_match, body) {
return body.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
})
.replace(/<!--.+?-->/g, '')
.match(/<title>.+?<\/title>/ig) || [])
.map(function (t) { return t.substring(7, t.length - 8) })
.join(' ')
}
내가 아닌 HTML 전문가입니다, 그래서 아마 몇 가장자리 경우를 놓친하지만 여기가하는 일입니다. 먼저 CDATA section을 찾습니다. 우리는 그 내부를 가져 와서 모든 불법적 인 성격을 동등한 존재로 바꾸고 <![CDATA[
과 ]]>
을 제거합니다. 다음으로, 우리는 모든 코멘트를 삭제합니다. 그 다음에는 각각의 제목을 일치시키고 일치 항목의 배열을 가져옵니다 (일치 항목의 배열을 추출하는 것은 하위 그룹 추출과 호환되지 않습니다). 이는 invalid-multiple-title
입니다. 편집 3 : 그런 다음 일치하지 않는지 확인한 후 .match()
은 null
을 반환하고 그 대신에 []
을 반환합니다. 이 방법으로, 우리는 항상 배열을가집니다. 그런 다음 처음부터 끝까지 태그를 자르고 (편집 3 :은이 단계에서 regexen을 더 이상 사용하지 않습니다.) 마지막으로 각 제목 단편에 공백을 넣습니다. 이건 내가 처리 할거야, , 케이스 1과 케이스 2를 생각하라. 법적 소송 (사례 1) 만 필요한 경우 마지막 세 줄 (}
제외)을 단 하나의 줄 .match(/<title>(.+?)<\/title>/)[0]
으로 바꿉니다. 그러나 이것이 많은 경우에 (비록) 생각할 수도 있지만, 나는 우리의 입력 (예 :, 제목 태그가 모두 함께 나타나고 원하는 위치)과 우리가 찾고있는 사실 단일 (집합) <title>...</title>
s) 및 일부 가장자리 케이스 또는 기타를 놓친 것 같습니다. 다행히도 더 나은 솔루션을 사용할 수 있다는 것을 알게 될 것입니다.
편집 1 : 나는 일반 텍스트 작업을 할 필요가 있다는 사실을 놓친; 내 원래 대답의 나머지 부분은 DOM에 대한 액세스 권한이 있다고 가정합니다. 나는 후손을 위해 이곳에 남겨 두겠다. 그러나 그것은 특별히 당신과 관련이 없다. 자바 스크립트에서 DOM에 대한 액세스 권한을 가지고 있다면 당신은 하나 적절한 HTML이 있다면
는 다음을 수행 할 수 title
태그 : 당신이 실제로 HTML이있는 경우
var titles = document.getElementsByTagName('title')
var titleText = titles.length > 0 ? titles[0].text : ''
그러나, 두 번째 이가지 경우처럼 보이는 당신은 우리에게 보여 줬지만 (나는 희망하지 않지만 결코 알지 못합니다), 그러면 당신은 다른 것을해야 할 것입니다. 파이어 폭스 나 사파리는 세 번째 케이스를 중첩 된 타이틀 태그로 취급하지 않고 리터럴 문자열 Title of the document <title> Continuing title
을 포함하는 하나의 타이틀 태그로 보았다. 당신은 처음 두 경우를 처리 할 필요가있는 경우,이 작동합니다 :
var titles = document.getElementsByTagName('title')
var tlength = titles.length
var titleText = ''
for (var i = 0; i < tlength; ++i)
titleText += titles[i].text
을 그리고 당신은 세 번째 경우가 있다면, 당신이해야 할 것은 외부 <title>
태그를 제거되는 수 약간 까다 롭지 만 아마도 그렇지 않다. 위와 같이 형식이 잘못된 HTML을 제외하고는 <title>
이 표시되지 않는다는 것을 알고 있다면 replace
메서드를 사용하여 제거 할 수 있습니다. 단일 standalone- <title>
, 경우에, 당신은, 당신이
// Edit 2: Case-insensitivity
var titles = document.getElementsByTagName('title')
var tlength = titles.length
var titleText = ''
for (var i = 0; i < tlength; ++i)
titleText += titles[i].text.replace(/<title>/ig,'')
<title>
경우가 다른 이유에 대한 올바른 문자열로 발생할 수있는하려는 잘못된 다중 standalone- <title>
경우
// Edit 2: Case-insensitivity
var titles = document.getElementsByTagName('title')
var titleText = titles.length > 0 ? titles[0].text.replace(/<title>/ig,'') : ''
을 원하는, 그러나 그때 당신은 곤경에 빠졌습니다. 을 알아 내야 만합니다. 문자열에 있었기 때문에 당신이 가정한다면 문자열을 바꿉니다. 그리고 제가 말할 수있는 한, 그렇게 할 수있는 좋은 방법이 없습니다. 그러나 합법적 인 HTML을 가지고 있기를 바랍니다.
Regex 및 기형의 HTML이 기뻐합니다. – kennytm
제목 태그는 제목 태그가 아니라 제목 * 요소 *입니다. http://perfectionkills.com/tag-is-not-an-element-or-is-it/ –
글쎄, 이것은 HTML이 아니기 때문에 그가 좋아하는 어떤 방식 으로든 부를 수 있습니다 :-) – RoToRa