2

誰かにばかげて簡単な質問をしましたが、自分で答えることはできません。2つの異なるオンラインテスターで機能する正規表現パターンがあります。そのうちの1つは.netベースです。

しかし、ここでは一致するものが見つかりません。誰か助けてもらえますか?目的は、F#チートの素敵なページをフィルタリングして印刷できるようにすることです:)。

私は私の弟を指導しています、彼はコーディングを学ぶ4週目です-これは彼の機能であり、私はそれが私を困惑させたことを告白します!どんな助けでも私はとても感謝しています!!

  Public Function FindCode(input As String)
    Dim pattern As String = "(?m)(<pre>)(.+)(<\/pre>)\B"
    Dim output As New Dictionary(Of Integer, String)
    Dim count As Integer

    For Each match As Match In Regex.Matches(input, pattern)
        output.Add(count, match.Value)
        count += 1
    Next
Return output.count
End Function

私は実行を取得しません、私は一致を取得しません。

例は

Some random markup <pre> and this stuff in the middle is what I'm after </pre> and there </pre> lots of these in one file </pre> which when I use Regexhero <pre> finds all the tags  </pre> 

このように、グループを使用して、pre/preタグ間のすべてのアイテムを一覧表示します。

このような迅速な対応に感謝します!

4

3 に答える 3

3

問題は、デフォルトでは貪欲なので、中間部分(.+)も含めて可能な限り一致していることだと思います。</pre>

に変更すると、(.+?)複数のエントリを取得する必要があります。次に、<pre>タグ内のテキストを見つけるには、の値をフェッチする必要がありますmatch.Groups[2]。は?が進まない-それは可能な限り少ない文字に一致します。.+

(?m)また、ちなみに、ここで何を達成するのかは明確ではありません。

(ああ、そしてもちろん、正規表現を使用してHTMLを解析することは一般的に悪い考えです...)

于 2013-02-25T08:18:11.003 に答える
1

(指定された正規表現に対して)正しい出力を取得しました。1つの一致には次のものが含まれます。

<pre> and this stuff in the middle is what I'm after </pre> and there </pre> lots of these in one file </pre> which when I use Regexhero <pre> finds all the tags </pre>

<pre>私はあなたが(ではなく</pre>)後に意味したと思うという事実は別としてand there...

(.+?)+はデフォルトで貪欲なので、おそらく使用したいと思うでしょう。


また、その理由(?m)/B(そしてなぜ最後に、しかし最初にではないのか)は明確ではありません。

于 2013-02-25T08:19:43.077 に答える
1

最初に、 Expressoで提供した式を試し、次にLinqPadで試しました。どちらも、意図したものとは異なる文字列全体を返しました。目的の結果が表示されない理由は2つあります。

  1. 正規表現自体
  2. サンプル文字列の問題(タグはペアワイズではありません。つまり、それぞれ<pre>をで閉じる必要があります</pre>

それ以外に、コードにいくつかの改善を提案します。

  1. マッチングの方法を変更します(以下の例では正規表現オプションを使用し、グループ化を許可しています)
  2. tagNameをパラメーターとして追加し、パラメーターを追加してタグの包含または除外を許可します
  3. カウント値の代わりにコレクションを返す

コードを見てください。正常に動作します(デバッグ用に値を出力する場合に備えて、 LinqPadにオプションのコメントアウトされた.Dump()ステートメントをいくつか追加しました)。

Public Function FindCode(input As String, tagName as string, includeTags as boolean)
    Const grpName as string = "pregroup"
    Dim pattern As String = "(<"+tagName+">)(?<"+grpName+">(\s|\w|')+)(</"+tagName+">)"  
    Dim output As New Dictionary(Of Integer, String)
    Dim count As Integer
    
    Dim options as RegexOptions = RegexOptions.IgnoreCase _
          or RegexOptions.IgnorePatternWhitespace _
          or RegexOptions.MultiLine or RegexOptions.ExplicitCapture
    ' options.Dump("options")
    Dim rx as Regex = new Regex(pattern, options)
    For Each m As Match In rx.Matches(input)
        Dim val as string=nothing
        if (includeTags) 
            val = m.Value
        else
            if(m.Groups(grpName).Success)
                val = m.Groups(grpName).Value 
            end if
        end if
        if not (val is nothing)
            ' val.Dump("Found #" & count+1)
            output.Add(count, val)
            count += 1
        end if
    Next    
    Return output
End Function

表現について:

  • (\s|\w)+の代わりに使用し.+ています。これは、空白と英数字のみが含まれ、角かっこは含まれないため、タグは含まれないためです。
  • (nnは文字の16進コード)を使用して、正規表現構文の特殊文字と競合する文字をエスケープします\xnn-注:これはここでは適用されません
  • グループ名を使用して、タグのコンテンツに簡単にアクセスします

Regexコードについて:includeTags違いがわかるようにパラメーターを追加しました(falseそれらを除外し、それらをtrue含めます)。式の照合方法に影響するため、RegexOptionsは常に適切に設定する必要があることに注意してください。

最後に、メインコードは次のとおりです。

Sub Main
    dim input as string = "Some random markup <pre> and this stuff in the middle is what I'm after </pre> and there <pre> lots of these in one file </pre> which when I use Regexhero <pre> finds all the tags  </pre>"
    dim result = FindCode(input, "pre", false)
    dim count as integer = result.Count()
    Console.WriteLine(string.Format("Found string {0} times.", count))
    Console.WriteLine("Findings:")
    for each s in result
        Console.WriteLine(string.format("'{0}'", s.Value))
    next
End Sub

これは出力します:

文字列が2回見つかりました。

調査結果:

'これらの多くを1つのファイルに'

'すべてのタグを検索します'

ただし、まだ1つの質問が残っています。最初に<pre>...</pre>一致しないのはなぜですか。部分文字列を見てください。空白でも英数字でもないため、一致しない部分文字列I'm afterが含まれています。正規表現で'指定することで追加でき、 3つの文字列すべてが表示されます。(\s|\w|')

于 2013-02-25T10:14:16.127 に答える