2

phpのpreg_match_allで使用するこの正常に機能する正規表現を使用して、文/文字列内の特定の単語の前に0〜x行、後に0〜y行を含む文字列を照合します。

'(?:[^\.?!<]*[\.?!]+){0,x}(?:[^\.?!]*)'.$word.'(?:[^\.?!]*)(?:[\.?!]+[^\.?!]*){0,y}'.'(?:[\.?!]+)'

ここで、特定のタグが発生したときに文字列を切り落とすようにします。だから私は上のこの文字列にこの部分を実装することを考えていました:

(?:(<\/?(?!'.$allowed_tags.')))

ここで、$ allowed_tagsは次のようなphp変数です。たとえば、次のようになります。'(frame|head|span|script)'

これを先読み、後読み、その他の条件で機能させようとしているにもかかわらず、適切に機能させることができず、残念ながら、これは私のプログラミングスキルをはるかに超えていることを認めなければなりません。

うまくいけば、誰かがこれで私を助けることができますか?私はあなたの天才の中の誰かができると確信しています:)

よろしくお願いします!

入出力の例:

たとえば、私はこの部分をつかみたいと思います:

<p>Tradition, Expansion, Exile.<br/>Individual paths in Chinese contemporary art </p><p>The contemporary <i>art world</i> craves for novelty: the best reason for Chinese art to be so trendy is also the <strong>worst one</strong>.</p>

この完全な文字列から:

<div readability="120"><p>Tradition, Expansion, Exile.<br/>Individual paths in Chinese contemporary art </p><p>The contemporary <i>art world</i> craves for novelty: the best reason for Chinese art to be so trendy is also the <strong>worst one</strong>.</p><div>

つまり、この例<p></p><i></i><strong></strong> <br/>ではタグが許可されており<div >、許可され</div>ていません。

4

1 に答える 1

1

コメントに従って「違法」として定義divおよびタグ付けすると、次の正規表現は、「違法」タグが含まれていない限り、文の前の文と後の文に一致します。spanxy$word

'(?:(?<=[.!?]|^)(?:(?<!<div|<\/div|<span|<\/span)>|[^>.!?])+[.!?]+){0,x}[^.!?]*'.$word.'[^.!?]*[.!?]+(?:(?:<(?!\/?div|\/?span)|[^<.!?])*[.!?]+){0,y}'

分割して説明します(引用符と文字列連結演算子を削除し、コメントと改行を追加して読みやすくしました):

                                     // 0 TO X LEADING SENTENCES
(?: ---------------------------------// do not create a capture group
  (?<=[.!?]|^) ----------------------// match only after sentence end or start of string
  (?: -------------------------------// do not create a capture group
    (?<!<div|<\/div|<span|<\/span)> -// match “&gt;” only if not preceded by span or div tags
    |[^>.!?] ------------------------// or any any other, non punctuation character
  )+ --------------------------------// one or more times
  [.!?]+ ----------------------------// followed by one or more punctuation characters
){0,x} ------------------------------// the whole sentence repeated 0 to x times
                                     // MIDDLE SENTENCE WITH KEYWORD
[^.!?]* -----------------------------// match 0 or more non-punctuation characters
$word -------------------------------// match string value of $word
[^.!?]* -----------------------------// match 0 or more non-punctuation characters
[.!?]+ ------------------------------// followed by one or more punctuation characters
                                     // 0 TO Y TRAILING SENTENCES
(?: ---------------------------------// do not create a capture group
  <(?!<\/?div|\/?span) --------------// match “&lt;” not followed by a “div” or “span” tag
  |[^<.!?] --------------------------// or any non-punctuation character that is not “&lt;”
  )* --------------------------------// zero or more times
  [.!?]+ ----------------------------// followed by one or more punctuation characters
){0,y} ------------------------------// the whole sentence repeated 0 to y times

以前に文を照合するために使用されたlookbehindアサーションは、属性のない開始タグと終了タグのみに一致し、lookbehindアサーションは可変長にすることができないため、$word文字通り開始タグと終了タグの両方のバリアントに一致する必要があることに注意してください。他にも制限と落とし穴があります。

  • 特に、正規表現が次の文を含む文のにある場合、正規表現は「違法」タグを返します。$word
  • また、文の「内部」とは、文字通り「前の文の句読点の終わりに続く」ことを意味します。これは、形式的には正しいものの、期待どおりではない場合があります。

これはすべて、問題に対する正規表現ベースのアプローチの制限を浮き彫りにします。この観点から、よりプログラム的なアプローチに切り替えると考えるかもしれません(タグに関係なくすべての文を配列に解析し、「違法な」タグをスキャンし、それに応じて配列をトリミングまたは拒否します。これにより、より柔軟なタグマッチングが可能になります。正規表現)の方がうまく機能します。文のような自然言語の構成要素を正規表現と正確に一致させるという根本的な難しさがなければ、あなたは正しいでしょう。この質問と回答で使用されている「文の分割」正規表現が次のようにどのように機能するかを考えてみましょう。

「TJフッカーは、スターシップエンタープライズ(!)の名声のW.シャトナーによって格子縞(原文のまま)でした」</ p>

かわいくないです。そして、どちらも結果ではありません。

于 2012-06-17T23:00:13.187 に答える