2016-07-15 7 views
1

私たちは、私は次の文字列変数を持っているとしましょう:ここ正規表現(順番に一致する文字を見つける。)

welcome = "StackExchange 2016" 
string_to_find = "Sx2016" 

、私は正規表現を使用してwelcomeの中の文字列string_to_findを見つけたいです。 string_to_findの各文字がwelcomeと同じ順番で表示されているかどうかを確認したいと思います。例えば

'S'は、などの文字列、'2''x'0'2'、および両方に'x'の前に来ているので、この表現はTrueに評価されます。

regexを使用してこれを行う簡単な方法はありますか?

答えて

1

使用ワイルドカードは*を繰り返し、.と一致:

expression = 'S.*x.*2.*0.*1.*6' 

ます。またjoin()でこの式を組み立てることができます。

expression = '.*'.join('Sx2016') 

それとも正規表現せずにそれを見つけることを、場所かどうかをチェックしますstring_to_findの各文字のうち、welcome内の文字は、string_to_findの文字がに存在しない場合を処理しますValueErrorをキャッチすることにより:

>>> welcome = "StackExchange 2016" 
>>> string_to_find = "Sx2016" 
>>> try: 
...  result = [welcome.index(c) for c in string_to_find] 
... except ValueError: 
...  result = None 
... 
>>> print(result and result == sorted(result)) 
True 
+0

私は彼がneccesarily 2016単語が一緒に接着されているという意味ではありませんと思います。 –

+0

'。* '。join(string_to_find)'についてはどうですか? –

3

あなたの答えはかなり簡単です。 .*の文字の組み合わせは、0文字以上に一致します。あなたの目的のために、あなたはそこのすべての文字の間にそれを置きます。 S.*x.*2.*0.*1.*6のように。このパターンが一致すると、文字列は条件に従います。

一般的な文字列については、文字間に.*パターンを挿入します。正規表現では解釈できない文字、点などの特殊文字をエスケープします。

0

この関数は、

import re 
def check_string(text, pattern): 
    return re.match('.*'.join(pattern), text) 

'.*'.join(pattern)あなたの必要性に合うかもしれない'.*'で区切られたすべてのあなたの文字でパターンを作成します。例えば

>> ".*".join("Sx2016") 
'S.*x.*2.*0.*1.*6' 
0

は実際に文字最良のあなたの目的は、より具体的であるサーブSx2016のようなパターンの配列を有する:

S[^x]*x[^2]*2[^0]*0[^1]*1[^6]*6 

あなたはこのような関数を定義し、チェックのこの種を取得することができます:

import re 
def contains_sequence(text, seq): 
    pattern = seq[0] + ''.join(map(lambda c: '[^' + c + ']*' + c, list(seq[1:]))) 
    return re.search(pattern, text) 

このアプローチは、複雑さのレイヤーを追加しますが、同様に2つの利点をもたらします。

  1. ドットつ星のアプローチは.*が使用されるたびに、シーケンスの最後まで行くとバックながら、正規表現エンジンは一度だけ文字列を歩くので、それは最速の一つです。同じ文字列での比較(〜1K文字):

  2. それは、同様の入力で複数行の文字列で動作します。

例コード

>>> sequence = 'Sx2016' 
>>> inputs = ['StackExchange2015','StackExchange2016','Stack\nExchange\n2015','Stach\nExchange\n2016'] 
>>> map(lambda x: x + ': yes' if contains_sequence(x,sequence) else x + ': no', inputs) 
['StackExchange2015: no', 'StackExchange2016: yes', 'Stack\nExchange\n2015: no', 'Stach\nExchange\n2016: yes'] 
関連する問題