2

中:preferences = 'Hello my name is paul. I hate puzzles.'
抽出したいHello my name is paul.

中:preferences = 'Salutations my name is richard. I love pizza. I hate rain.'
抽出したいSalutations my name is richard. I love pizza.

中:preferences = 'Hi my name is bob. I enjoy ice cream.'
抽出したいHi my name is bob. I enjoy ice cream.

言い換えれば、私はしたいです

  • 常に捨てるpreferences = '
  • という単語が含まれる最後の文 ( で区切られている) を破棄します(存在する場合) 。.hate
  • 最終を捨てる'

私の問題は、正規表現が最初で停止し.、後続の文を抽出しないことです。

ありがとう。

4

4 に答える 4

2

正規表現を使用して、目的を達成できます。

^preferences\s*=\s*'(.*?\.)(?:[^.]*\bhate\b[^.]*\.)?'$

それはそれほどトリッキーではありません:

  • (.*?\.)- group でキャプチャされる、期待される出力と一致します$1。パターンは「文」(定義したとおり)に一致しますが、必要なだけ遅延(*?)します。
  • (?:[^.]*\bhate\b[^.]*\.)?- オプションで最後の文に一致しますが、「ヘイト」が含まれている場合のみです。一致する可能性があり、それが最後のセンテンスである場合、マッチング エンジンはバックトラックせず、最後のセンテンスはキャプチャされたグループに含まれません。

Rubular での実際の例を次に示します: http://www.rubular.com/r/qTuMmB3ySj (新しい行の一致を避けるために、いくつかの場所に
追加しました)\r\n[^.]

正直なところ、ここで単一の正規表現を使用するよりも、それを避けることができれば、より良い結果を得ることができます。

于 2012-04-07T21:23:21.183 に答える
1

これは正規表現を使用していませんが、目的を達成します

List<string> resultsList = new List<string);


for(int i = 0; i < preferences.Count; i++)
{
    List<string> tempList = new List<string);
    //creating the substring eliminates the "preferences = '" as well as the "'" at end of string
    //this line also splits each string from the preferences string list into the tempList array
    tempList = preferences[i].Substring(15, preferences[i].Length - 15 - 1).Split('.').ToList();

    string buildFinalString = "";

    //traverse tempList and only add string to buildFinalString if it does not contain "hate"
    foreach(string x in tempList)
    {
        if(!x.Contains("hate").ToUpper() || !x.Contains("hate").ToLower())
        {
             buildFinalString = buildFinalString + " " + x;
        }
    }
    resultsList.Add(buildFinalString);
}

または、「tempList」配列の最後の文字列で憎悪という言葉をチェックしたいだけであれば、これも可能です...

于 2012-04-07T21:16:12.357 に答える
1

私は2つの正規表現でそれをしました。1 つ目は を削除するために使用されpreferences = '...'、2 つ目は「ヘイト」という単語を含む文を削除するために使用されます。2 番目の正規表現は、肯定的な後読みを使用して、setntences を空の文字列のキーワードに置き換えます。

String[] tests = {
    "preferences = 'Hello my name is Paul. I hate puzzles.'",
    "preferences = 'Salutations my name is Richard. I love pizza. I hate rain.'",
    "preferences = 'Hi my name is Bob. Regex turns me on.'"};
var re1 = new Regex("preferences = '(.*)'");
var re2 = new Regex("([^\\.]+(?<=.*\\bhate\\b.*)).\\s*");

for (int i=0; i < tests.Length; i++)
{
    Console.WriteLine("{0}: {1}", i, tests[i]);
    var m = re1.Match(tests[i]);
    if (m.Success)
    {
        var s = m.Groups[1].ToString();
        s = re2.Replace(s,"");
        Console.WriteLine("   {1}", i, s);
    }
    Console.WriteLine();
}

最後の文にフラグ ワードが含まれている場合は、最後の文だけを削除するように要求したため、これはまさにあなたが望むものではない可能性があります。ただし、単語が含まれている場合に最後の文だけを削除したい場合は、簡単に調整できます。その場合、re2 の末尾に $ を追加するだけです。

于 2012-04-07T21:32:19.283 に答える
0

これらのいずれかが機能する可能性があります-

Match[1] バッファの結果

preferences\s*=\s*'([^']*?)(?:(?<=[.'])[^.']*hate[^.']*\.\s*)?'

また

Match[1] バッファの結果

preferences\s*=\s*'([^']*?)(?=(?<=[.'])[^.']*hate[^.']*\.\s*'|')

また

(.Net のみ)
Match[0] バッファの結果

(?<=preferences\s*=\s*')[^']*?(?=(?<=[.'])[^.']*hate[^.']*\.\s*'|')

編集: 'hate' の周りに \b を使用したり、begin/end コンストラクト ^$ を使用したりしないでください。必要な場合は自由に追加してください。余談ですが、自由形式のテキストを含む文字列変数を区切るコンテキストで、アポストロフィとピリオドがどのように使用されるかは不可解です。

于 2012-04-07T22:04:30.657 に答える