2016-09-09 9 views
1

にターゲットの前と後の単語をキャプチャする:コールスタックポインタがバインドスタックを超えた場合、ソフトウェアでは正規表現は、我々が持っていると仮定したテキストルビー

を、スタックオーバーフローが発生します。コールスタックは、限られた量のアドレス空間で構成され、多くの場合、プログラムのstartで決定されます。コールスタックのサイズは、プログラミング言語、マシンアーキテクチャ、マルチスレッド、使用可能なメモリの量など、多くの要因によって異なります。

私がやっていることは、特定の単語(ターゲット)の前後に2単語を見つけることです。たとえば、ターゲットが単語の場合、の場合は、「at」「the」(左)と「of」「the」(右)と一致する必要があります。私はルビーで次のメソッドを使用していますが、一致するものは返しません。私の正規表現で修正するためのヒント私もRegex.escapeの代わりに "#{target}"を試しました。

def checkWords(target, text, numLeft = 2, numRight = 2) 

     regex = "" 
     regex += " (\\S+) " * numLeft 
     regex += Regexp.escape(target) 
     regex += " (\\S+)" * numRight 

     pattern = Regexp.new(regex, Regexp::IGNORECASE) 
     matches = pattern.match(text) 

     return true if matches 
    end 

編集:印刷

正規表現:Wiktor第Stribiżewに基づいて

(\S+) (\S+) "£52" (\S+) (\S+) 

編集:

def checkWords(target, text, numLeft = 2, numRight = 2) 

pattern = Regexp.new(/#{"(\\S+) "*numLeft}#{Regexp.escape(target)}#{" (\\S+)"*numRight}/i) 
matches = pattern.match(text) 

end 
+0

'regex'の値をログに記録して質問に追加してください。 –

+0

'(\\ S +) 'のスペースが2倍になります。 'regex + ="(\\ S +) "* numLeft'を使います。 –

+0

は私の正規表現のプリントを含んでいます – Vas

答えて

1

あなたはスペースが最初(\\S+)の周りに倍増している:

regex += " (\\S+) " * numLeft 
     ^

あなたはそれを倍増させます、この部分は012のように見えます- (\\S+)の間に2つのスペースがあります。

だから、あなたの場合には、ちょうど

def checkWords(target, text, numLeft = 2, numRight = 2) 
    text[/#{"(\\S+) "*numLeft}#{Regexp.escape(target)}#{" (\\S+)"*numRight}/i] 
end 
puts checkWords('start', 'In software, a stack overflow occurs if the call stack pointer exceeds the stack bound. The call stack may consist of a limited amount of address space, often determined at the start of the program. The size of the call stack depends on many factors, including the programming language, machine architecture, multi-threading, and amount of available memory.') 

を使用すると、次の(\S+)に空白の後+を追加するのは良いアイデアかもしれませんRuby demo

を参照してください。キャプチャが必要ない場合は、\S+から括弧を削除します。

+0

私はそれも間隔なしでそれを試してみました。まだ一致が返ってこない – Vas

+0

私の答えにデモリンクがありますが、うまくいきます。あなたのためにはうまくいかないバイブルを私に見せてください。あなたが達成する必要があることを説明してください。 –

+0

それは私のために働いていません。おそらく、テストした目標が10,500ポンドを目標としているからでしょうか? – Vas

3
▶ input[/(\S+\s+){,2}start(\s+\S+){,2}/i] 
#⇒ "at the start of the" 

より一般的な:

後に句読点を処理するために
▶ target = 'start' 
▶ input[/(\S+\s+){,2}#{Regexp.escape target}(\s+\S+){,2}/i] 
#⇒ "at the start of the" 

▶ target = 'start' 
▶ input[/(\S+\s+){,2}#{Regexp.escape target}\p{P}?(\s+\S+){,2}/i] 
#⇒ "at the start of the" 

あなたの関数は次のようになります。

def checkWords(target, text, numLeft = 2, numRight = 2) 
    text =~ /(\S+\s+){,#{numLeft}}#{Regexp.escape target}\p{P}?(\s+\S+){,#{numRight}}/i 
end 
+2

ところで、検索語に句読点が付いていれば、2語は得られません。 –

+0

@WiktorStribiżewはい、本当にありがとうございます。更新しました。 – mudasobwa

+0

Regexが私のために働いていない – Vas

2

あなたが見ているケースでは、単語以外の文字にテキストを分割してから、目的の単語を分割して検索する方が良いと思います。いったん見つけたら、必要な結果を得るために単語の配列の適切なスライスを取ることは非常に簡単です。例えば

def check_words(target, text, num_left = 2, num_right = 2) 
    # Split the text using the regex /\W+/ (matches non-word characters) 
    words = text.split /\W+/ 
    # Iterate over the words in the array 
    # Enumerable#each_with_index includes the index, so retrieving the surrounding 
    # words is a snap 
    words.each_with_index do |word, index| 
    if word == target 
     # Make a hash with two Symbol keys and small 
     # arrays containing the desired words 
     return { 
     before: words.slice(index - num_left, num_left), 
     after: words.slice(index, num_right) 
     } 
    end 
    end 
end 

これは、そのようにのように呼び出すことができます。

check_words('start', text) 

そして、それはキーワードの後num_left言葉の前とnum_right単語を含むハッシュを返します。

{:before=>["at", "the"], :after=>["start", "of"]} 

{before: ...}構文Ruby 2の場合は{:before => ...}です。いずれの構文も正常に動作します。

また、RubyのドキュメントRegexpについては、まだ理解していない場合は興味があります。

+0

有用で面白いですが、数字を含めることにも興味があれば、これは問題になると思います。 – Vas

+0

@Vas Nope!単語以外の文字には数字は含まれないので、数字は問題ありません。さらに、語句以外の文字_do_には句読点が含まれているため、句読点も正しく表示されます。 – andyg0808

+0

通貨記号も含まれていますか? – Vas

関連する問題