2016-04-27 1 views
1

サブストリングのセットのいずれかを結合することによって、指定されたストリングを作成できるかどうかを調べたいと思います。具体例として、正規表現sg|ge|ne|n|sのどの部分に一致するかによって文字列"sgene"を分割したいと考えています。答えは、"s""ge""ne"です。なぜなら、これらの3つの部分は、文字列が正規表現、目的の部分文字列のセットに分解される方法であるからです。String.scanとFindAllStringの一致動作をオーバーライドするにはどうすればよいですか?

Goにはregexp.(*Regexp).FindAllStringがあり、RubyにはRegexp.scanがあります。私のコードでは、正規表現が重複しているので、スーパーストリングの前後に部分文字列を並べるかどうかにかかわらず、1つのマッチが失われます。ここで


が行くで問題を再現するためのプログラムである:

package main 

import (
    "fmt" 
    "regexp" 
) 

func main() { 
    str := "sgene" 
    superBeforeSub := regexp.MustCompile("sg|ge|ne|n|s") 
    subBeforeSuper := regexp.MustCompile("n|s|sg|ge|ne") 
    regexes := []*regexp.Regexp{superBeforeSub, subBeforeSuper} 
    for _, rgx := range regexes { 
     fmt.Println(rgx.MatchString(str), rgx.FindAllString(str, -1)) 
    } 
} 

このプログラムの出力は:用

true [sg ne] 
true [s ge n] 

そして、ここではRubyで同じプログラムである(問題ルビーもhereと表示されます):

str = "sgene" 
regexes = [/sg|ge|ne|n|s/, /n|s|sg|ge|ne/] 
regexes.each do |regex| 
    puts "%s %s" % [(regex === str).to_s, str.scan(regex).inspect] 
end 

それは出力:

true ["sg", "ne"] 
true ["s", "ge", "n"] 

を正規表現エンジンは、文字列は正規表現でマッチさせることができることを知っているが、FindAllStringscanはそれをboolean型の一致がない方法と一致していません。彼らは少なくとも1つのeを無視する貪欲な最長一致検索を使用しているようです。どのように正規表現を使用して文字列をいずれかの言語で[s ge ne]に分割できますか?

+0

人のように、パターンの末尾に移動「N」だった、それは全く不明で、私が求めていたものではありません。私はこの質問に多くの努力を払いました。文字列を '[s ge ne]'に分割したいのですが、いずれの言語もその能力を提供していません。 – EMBLEM

+1

分割操作に適用するルールが完全に理解されていません。もう少しサンプルをくれますか? 目的は何ですか? –

+0

@pascalbetz文字列は 's'で始まり、' ge'とそれに続く 'ne'で構成され、すべてが正規表現の一部です。ブール値マッチはこれを知っていますが、配列のマッチは文字列をそれらの部分に分解しません。正規表現と一致する部分で文字列を分割したい。さて、もし私が文字列 "sgen"を持っていたら、これらはすべて正規表現の一部であるので、 '[s、ge、n]'を期待します。あるいは '遺伝子'から 'ge'、 'ne's、' s'は正規表現の一部分なので '[ge、ne、s]'と期待します。目的は、いくつかの可能な部分文字列のいずれかを一緒に結合することによって、指定された文字列を作成できるかどうかを判断することです。 – EMBLEM

答えて

0

この回答はRubyのみに関するものです。

私が理解したよう我々は正規表現にこの正規表現については

r = /sg|ge|ne|n|s/ 

"sgene".scan r 
    #=> ["sg", "ne"] 

を与えている、あなたは正規表現の要素の順序の並び替えを見つけたい、r_new、などその

"sgene".scan(r_new).join == "sgene" 

同じように、あなたは配列と文字列

arr = ["sg", "ge", "ne", "n", "s"] 
target = "sgene" 

arrの要素のいくつかまたは全ての順列があるかどうかを判断したい、perm、このよう

target == perm.join 

ことと、これは正規表現を使用して行うことができるかどうか尋ねています。私はできると信じていますが、それを証明することはできません。さらに、このコメントのいくつかはそのことに疑問を投げかけている。

ただし、以下のように行うことができます。

(1..arr.size).each_with_object([]) { |n, perms| 
    arr.permutation(n).each { |p| perms << p if p.join==target } } 
    #=> [["s", "ge", "ne"]] 

働くすべての順列が識別されるように、私は、selectはなく、any?を使用。たとえば、

+0

これは大丈夫ですが、Goでは動作しません。正規表現よりも効率が悪いです。 – EMBLEM

+0

あなたはRuby *や* Goと言っています。これをGoでコーディングすることができない場合(私が驚くべきことに思う)、それは解決策の弱点とはみなされません。これは正規表現を使ってこれを行うことができれば、正規表現よりも効率が悪いだけです。 –

0

実際に何をしようとしているのか分かりませんが、単純に正規表現の記号の順序を変更することができます。 これはワイルドカードを使用していないため、欲張りではなく貪欲ではありません。

正規表現の問題の順序で単純に一致します。

ここに修正バージョンon Playがあります。唯一の違いは、正規表現自体を変更して目的の出力を得ることです。

私はすべての

を閉じるために投票し s|sg|ge|ne|n

package main 

import (
    "fmt" 
    "regexp" 
) 

func main() { 
    str := "sgene" 
    superBeforeSub := regexp.MustCompile("sg|ge|ne|n|s") 
    subBeforeSuper := regexp.MustCompile("n|s|sg|ge|ne") 
    orderIActuallyWant := regexp.MustCompile("s|sg|ge|ne|n") 
    regexes := []*regexp.Regexp{superBeforeSub, subBeforeSuper, orderIActuallyWant} 
    for _, rgx := range regexes { 
     fmt.Println(rgx.MatchString(str), rgx.FindAllString(str, -1)) 
    } 
} 
+0

あなたの答えは一般的なケースでは機能しません。それは私がコメント[ここ]で発見した問題を抱えている(http://stackoverflow.com/questions/25819437/is-there-a-version-of-rubys-regexp-match-that-responds-to-the-order) -of-the-matc)あなたの正規表現は "sg"を正しくマッチさせることはできません。それを 's'に分割します。それは私が皆に伝えようとしてきたことです!スーパーストリングの前後にサブストリングを置いても、それはすべてのものと一致しません! – EMBLEM

+0

正規表現はパターンの順番で一致するので、sgをsの前にしたい場合は、 'sg | s | ge | ne | n'に変更してください。 –

+0

私の理解は、正規表現の並べ替えは、文字列 '' sgene "'だけでなく、任意の文字列に対して行われることです。エンブレム、それは正しい? –

関連する問題