문제

나를 추출하기 위해 노력하고의 특성 앵커 태그(<a>).지금까지 나는 이 표현:

(?<name>\b\w+\b)\s*=\s*("(?<value>[^"]*)"|'(?<value>[^']*)'|(?<value>[^"'<> \s]+)\s*)+

는 작품을 위해 같은 문자열

<a href="test.html" class="xyz">

과(작은 따옴표)

<a href='test.html' class="xyz">

지 없이 문자열을 따옴표:

<a href=test.html class=xyz>

어떻게 수정할 수 있습니 regex 만들기와 함께 작동 특성이없는 따옴표?또는 더 좋은 방법이 있을까요?

감사합니다!

업데이트: 감사에 대한 모든 좋은 의견과 조언까지.이 언급하지 않았다:내가 슬프게도 있을 패치/수정 코드로 작성되지 않습니다.시간이 없/는 돈을 다시 쓰이는 물건 밑에서습니다.

도움이 되었습니까?

해결책

당신이 같은 요소가 있다면

<name attribute=value attribute="value" attribute='value'>

이 regex는 각 속성 이름과 값을 연속적으로 찾는 데 사용될 수 있습니다.

(\S+)=["']?((?:.(?!["']?\s+(?:\S+)=|[>"']))+.)["']?

적용 :

<a href=test.html class=xyz>
<a href="test.html" class="xyz">
<a href='test.html' class="xyz">

그것은 양보 할 것입니다 :

'href' => 'test.html'
'class' => 'xyz'

메모: 이것은 숫자 속성 값과 함께 작동하지 않습니다 <div id="1"> 작동하지 않습니다.

다른 팁

Regexp를 통해 HTML을 구문 분석하지 않는 조언은 유효하지만 다음은 다음과 같은 표현을 수행하는 표현입니다.

/
   \G                     # start where the last match left off
   (?>                    # begin non-backtracking expression
       .*?                # *anything* until...
       <[Aa]\b            # an anchor tag
    )??                   # but look ahead to see that the rest of the expression
                          #    does not match.
    \s+                   # at least one space
    ( \p{Alpha}           # Our first capture, starting with one alpha
      \p{Alnum}*          # followed by any number of alphanumeric characters
    )                     # end capture #1
    (?: \s* = \s*         # a group starting with a '=', possibly surrounded by spaces.
        (?: (['"])        # capture a single quote character
            (.*?)         # anything else
             \2           # which ever quote character we captured before
        |   ( [^>\s'"]+ ) # any number of non-( '>', space, quote ) chars
        )                 # end group
     )?                   # attribute value was optional
/msx;

"하지만 잠깐만 요." " *코멘트는 어떻습니까?!?!" 좋아, 그럼 당신은 교체 할 수 있습니다 . (CDATA 섹션도 처리합니다.)

(?:[^<]|<[^!]|<![^-\[]|<!\[(?!CDATA)|<!\[CDATA\[.*?\]\]>|<!--(?:[^-]|-[^-])*-->)
  • 또한 Perl 5.10 (그리고 PCRE라고 생각하는)에 따라 대체를 실행하고 싶다면 \K 속성 이름 바로 앞에서 건너 뛰고 싶은 모든 물건을 캡처하는 것에 대해 걱정할 필요가 없습니다.

토큰 만트라 응답 : 정규 표현식을 사용하여 조정/수정/수확/또는 달리 HTML/XML을 생산해서는 안됩니다.

'및 "와 같은 코너 케이스 조건부도 설명해야합니다. 자신의 발명.

나는 당신이 인정 받고, 테스트를 거치고, 당신이 어떤 것을 사용하는지에 관심이 없으며, 당신은 하나를 사용하는 한, 당신은 하나를 사용하는 한, 당신은 어떤 것을 사용하는지 상관하지 않습니다.

my $foo  = Someclass->parse( $xmlstring ); 
my @links = $foo->getChildrenByTagName("a"); 
my @srcs = map { $_->getAttribute("src") } @links; 
# @srcs now contains an array of src attributes extracted from the page. 

다른 모든 사람과 동의하기 위해 : regexp를 사용하여 HTML을 구문 분석하지 마십시오.

올바른 HTML조차도 속성을 선택할 수있는 표현식을 만들 수는 없으며 가능한 모든 기형 변형을 신경 쓰지 마십시오. 귀하의 Regexp는 인용문의 잘못된 부족에 대처하려고 시도하지 않아도 이미 읽을 수 없습니다. 실제 HTML의 공포로 더 쫓아 가면 신뢰할 수없는 표현의 인재 할 수없는 덩어리로 자신을 미치게 할 것입니다.

Broken HTML을 읽거나 유효한 XHTML로 수정할 수있는 기존 라이브러리가 있습니다. 그것을 써.

여러 캡처에 동일한 이름을 사용할 수 없습니다. 따라서 캡처 명명 된 표현식에서 수량자를 사용할 수 없습니다.

따라서 명명 된 캡처를 사용하지 마십시오.

(?:(\b\w+\b)\s*=\s*("[^"]*"|'[^']*'|[^"'<>\s]+)\s+)+

또는이 표현에서 수량자를 사용하지 마십시오.

(?<name>\b\w+\b)\s*=\s*(?<value>"[^"]*"|'[^']*'|[^"'<>\s]+)

이것은 또한 속성 값과 같은 속성 값을 허용합니다 bar=' baz='quux:

foo="bar=' baz='quux"

글쎄, 단점은 나중에 선행 및 후행 인용문을 제거해야한다는 것입니다.

PHP (PCRE) and Python

Simple attribute extraction (See it working):

((?:(?!\s|=).)*)\s*?=\s*?["']?((?:(?<=")(?:(?<=\\)"|[^"])*|(?<=')(?:(?<=\\)'|[^'])*)|(?:(?!"|')(?:(?!\/>|>|\s).)+))

Or with tag opening / closure verification, tag name retrieval and comment escaping. This expression foresees unquoted / quoted, single / double quotes, escaped quotes inside attributes, spaces around equals signs, different number of attributes, check only for attributes inside tags, and manage different quotes within an attribute value. (See it working):

(?:\<\!\-\-(?:(?!\-\-\>)\r\n?|\n|.)*?-\-\>)|(?:<(\S+)\s+(?=.*>)|(?<=[=\s])\G)(?:((?:(?!\s|=).)*)\s*?=\s*?[\"']?((?:(?<=\")(?:(?<=\\)\"|[^\"])*|(?<=')(?:(?<=\\)'|[^'])*)|(?:(?!\"|')(?:(?!\/>|>|\s).)+))[\"']?\s*)

(Works better with the "gisx" flags.)


Javascript

As Javascript regular expressions don't support look-behinds, it won't support most features of the previous expressions I propose. But in case it might fit someone's needs, you could try this version. (See it working).

(\S+)=[\'"]?((?:(?!\/>|>|"|\'|\s).)+)

Splattne,

@Vonc 솔루션은 부분적으로 작동하지만 태그에 인용문이 혼합되어 있고 인용 된 경우 문제가 있습니다.

이것은 혼합 된 속성으로 작동합니다

$pat_attributes = "(\S+)=(\"|'| |)(.*)(\"|'| |>)"

테스트하려면

<?php
$pat_attributes = "(\S+)=(\"|'| |)(.*)(\"|'| |>)"

$code = '    <IMG title=09.jpg alt=09.jpg src="http://example.com.jpg?v=185579" border=0 mce_src="example.com.jpg?v=185579"
    ';

preg_match_all( "@$pat_attributes@isU", $code, $ms);
var_dump( $ms );

$code = '
<a href=test.html class=xyz>
<a href="test.html" class="xyz">
<a href=\'test.html\' class="xyz">
<img src="http://"/>      ';

preg_match_all( "@$pat_attributes@isU", $code, $ms);

var_dump( $ms );

$ MS에는 2 차 및 세 번째 요소에 키와 값이 포함됩니다.

$keys = $ms[1];
$values = $ms[2];

이것은 HTML 태그에서 속성을 추출하는 가장 좋은 동정인입니다.

# 인용문 내부의 경기를 다듬습니다 (단일 또는 이중)

(\S+)\s*=\s*([']|["])\s*([\W\w]*?)\s*\2

# 트림없이

(\S+)\s*=\s*([']|["])([\W\w]*?)\2

장점 :

  • 인용문 내부의 내용을 다룰 수 있습니다.
  • 따옴표의 모든 특수 ASCII 문자를 일치시킵니다.
  • 제목 = "your miny"가 있다면 Regex가 깨지지 않았습니다.

단점 :

  • 3 개의 그룹을 반환합니다. 먼저 속성은 인용문 ( "| ')과 결국 인용문 내부의 속성이 다음과 같습니다. <div title="You're"> 결과는 그룹 1 : 제목, 그룹 2 : ", 그룹 3 : 당신입니다.

이것은 온라인 Regex 예입니다.https://regex101.com/r/avz4ug/13



일반적 으로이 Regex를 사용하여 HTML 태그를 추출합니다.

같은 태그 유형을 사용하지 않으면 권장합니다. <div, <span, 등.

<[^/]+?(?:\".*?\"|'.*?'|.*?)*?>

예를 들어:

<div title="a>b=c<d" data-type='a>b=c<d'>Hello</div>
<span style="color: >=<red">Nothing</span>
# Returns 
# <div title="a>b=c<d" data-type='a>b=c<d'>
# <span style="color: >=<red">

이것은 온라인 Regex 예입니다.https://regex101.com/r/avz4ug/15

이 regex의 버그는 다음과 같습니다.

<div[^/]+?(?:\".*?\"|'.*?'|.*?)*?>

이 태그에서 :

<article title="a>b=c<d" data-type='a>b=c<div '>Hello</article>

보고 <div '> 그러나 일치를 반환해서는 안됩니다.

Match:  <div '>

"해결"하려면이를 제거하십시오 [^/]+? 무늬:

<div(?:\".*?\"|'.*?'|.*?)*?>


대답 #317081 양호하지만 이러한 경우와 제대로 일치하지 않습니다.

<div id="a"> # It returns "a instead of a
<div style=""> # It doesn't match instead of return only an empty property
<div title = "c"> # It not recognize the space between the equal (=)

이것은 개선입니다.

(\S+)\s*=\s*["']?((?:.(?!["']?\s+(?:\S+)=|[>"']))?[^"']*)["']?

vs

(\S+)=["']?((?:.(?!["']?\s+(?:\S+)=|[>"']))+.)["']?

동일한 신호 사이의 공간을 피하십시오 : ( s+)에스*=에스*((?:...

마지막 +를 변경하십시오. for : | [> " ']))?[^"']*)["']?

이것은 온라인 Regex 예입니다.https://regex101.com/r/avz4ug/8

이와 같은 것이 도움이 될 수 있습니다

'(\S+)\s*?=\s*([\'"])(.*?|)\2

나는 당신이 사용하는 것이 좋습니다 HTML 깔끔한 HTML을 XHTML로 변환 한 다음 적절한 XPath 표현식을 사용하여 속성을 추출하십시오.

일반이 되려면 A 태그의 정확한 사양을 살펴 봐야합니다. 여기. 그러나 그에도 불구하고 완벽한 Regexp를 수행한다면 HTML을 잘못 알고 있다면 어떨까요?

나는 당신이 함께 일하는 언어에 따라 html을 구문 분석하기 위해 도서관을 찾는 것이 좋습니다 : 예 : Python의 아름다운 수프처럼.

.NET에있는 경우 HTML 민첩성 팩을 추천합니다. 기름 포괄적 인 HTML에서도 매우 강력합니다.

그런 다음 XPath를 사용할 수 있습니다.

나는 단일 정규 표현 만 사용하는 전략을 재고 할 것입니다. 물론 모든 일을하는 하나의 정규 표현을 생각해내는 것은 좋은 게임입니다. 그러나 유지 가능성의 관점에서 당신은 양쪽 발로 자신을 쏘려고합니다.

HTML의 태그 및 속성에는 양식이 있습니다

<tag 
   attrnovalue 
   attrnoquote=bli 
   attrdoublequote="blah 'blah'"
   attrsinglequote='bloob "bloob"' >

속성과 일치하려면 Regex가 필요합니다 attr 그것은 네 가지 형태 중 하나를 찾습니다. 그런 다음 HTML 태그 내에서 일치 만보고되어야합니다. 올바른 정규식이 있다고 가정하면 총 정규식은 다음과 같습니다.

attr(?=(attr)*\s*/?\s*>)

Lookahead는 다른 속성과 닫는 태그 만 속성을 따르도록합니다. 나는 다음과 같은 정규 표현을 사용합니다 attr:

\s+(\w+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^><"'\s]+)))?

중요하지 않은 그룹은 캡처하지 않습니다. 첫 번째 일치하는 그룹 $1 속성의 이름을 제공하고 값은 다음 중 하나입니다. $2또는 $3 또는 $4. 나는 사용한다 $2$3$4 값을 추출합니다. 최종 정규식은입니다

\s+(\w+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^><"'\s]+)))?(?=(?:\s+\w+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^><"'\s]+))?)*\s*/?\s*>)

참고 : 나는 룩 이드에서 모든 불필요한 그룹을 제거하고 나머지 그룹을 캡처하지 않게 만들었습니다.

나는 또한 이것을 필요로하고 속성을 구문 분석하기위한 함수를 썼습니다. 여기에서 얻을 수 있습니다.

https://gist.github.com/4153580

(참고 : Regex를 사용하지 않습니다)

내가 만든 PHP 능 을 추출 할 수 있는 속성의 모든 HTML 태그가 있습니다.그것은 또한 처리할 수 있는 속성 disabled 는 값이 없고,또한지 여부를 결정할 수 있는 태그는 독립형 태그(가 닫 태그)또는(있을 닫 태그)에 의해 확인 content 결과:

/*! Based on <https://github.com/mecha-cms/cms/blob/master/system/kernel/converter.php> */
function extract_html_attributes($input) {
    if( ! preg_match('#^(<)([a-z0-9\-._:]+)((\s)+(.*?))?((>)([\s\S]*?)((<)\/\2(>))|(\s)*\/?(>))$#im', $input, $matches)) return false;
    $matches[5] = preg_replace('#(^|(\s)+)([a-z0-9\-]+)(=)(")(")#i', '$1$2$3$4$5<attr:value>$6', $matches[5]);
    $results = array(
        'element' => $matches[2],
        'attributes' => null,
        'content' => isset($matches[8]) && $matches[9] == '</' . $matches[2] . '>' ? $matches[8] : null
    );
    if(preg_match_all('#([a-z0-9\-]+)((=)(")(.*?)("))?(?:(\s)|$)#i', $matches[5], $attrs)) {
        $results['attributes'] = array();
        foreach($attrs[1] as $i => $attr) {
            $results['attributes'][$attr] = isset($attrs[5][$i]) && ! empty($attrs[5][$i]) ? ($attrs[5][$i] != '<attr:value>' ? $attrs[5][$i] : "") : $attr;
        }
    }
    return $results;
}

테스트 코드

$test = array(
    '<div class="foo" id="bar" data-test="1000">',
    '<div>',
    '<div class="foo" id="bar" data-test="1000">test content</div>',
    '<div>test content</div>',
    '<div>test content</span>',
    '<div>test content',
    '<div></div>',
    '<div class="foo" id="bar" data-test="1000"/>',
    '<div class="foo" id="bar" data-test="1000" />',
    '< div  class="foo"     id="bar"   data-test="1000"       />',
    '<div class id data-test>',
    '<id="foo" data-test="1000">',
    '<id data-test>',
    '<select name="foo" id="bar" empty-value-test="" selected disabled><option value="1">Option 1</option></select>'
);

foreach($test as $t) {
    var_dump($t, extract_html_attributes($t));
    echo '<hr>';
}

이것은 나를 위해 작동합니다. 또한 내가 만난 일부 종료 사례를 고려합니다.

XML 파서 에이 Regex를 사용하고 있습니다

(?<=\s)[^><:\s]*=*(?=[>,\s])

요소 추출 :

var buttonMatcherRegExp=/<a[\s\S]*?>[\s\S]*?<\/a>/;
htmlStr=string.match( buttonMatcherRegExp )[0]

그런 다음 jQuery를 사용하여 원하는 비트를 구문 분석하고 추출하십시오.

$(htmlStr).attr('style') 

이것을 살펴보십시오Regex & PHP- IMG 태그에서 SRC 속성을 고립

아마도 당신은 Dom을 걸어 가서 원하는 속성을 얻을 수 있습니다. 그것은 나에게 잘 작동합니다.

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