私はこの正規表現を取得しました:
ss = "spam bar ds<hai bye>sd baz eggs ZQ<boo <abv> foo>WX "
reg = re.compile('(?:'
'\S*?'
'<'
'[^<>]*?'
'(?:<[^<>]*>[^<>]*)*'
'[^<>]*?'
'>'
')?'
'\S+')
print reg.findall(ss)
結果
['spam', 'bar', 'ds<hai bye>sd', 'baz', 'eggs',
'ZQ<boo <abv> foo>WX']
編集1
Cartrooのコメントの後、より正確な新しい正規表現:
import re
pat = ('(?<!\S)' # absence of non-whitespace before
'(?:'
'[^\s<>]+'
'|' # OR
'(?:[^\s<>]*)'
'(?:'
'<'
'[^<>]*?'
'(?:<[^<>]*?>[^<>]*)*'
'[^<>]*?'
'>'
')'
'(?:[^\s<>]*)'
')'
'(?!\S)' # absence of non-whitespace after)
)
reg = re.compile(pat)
ss = ("spam i>j bar ds<hai bye>sd baz eggs Z<boo <abv>"
" foo>W ttt <two<;>*<:> three> ")
print '%s\n' % ss
print reg.findall(ss)
ss = "a<b<E1>c>d <b<E2>c>d <b<E3>c> a<<E4>c>d <<E5>>d
<<E6>> <<>>"
print '\n\n%s\n' % ss
print reg.findall(ss)
結果
spam i>j bar ds<hai bye>sd baz eggs Z<boo <abv> foo>W
ttt <two<;>*<:> three>
['spam', 'bar', 'ds<hai bye>sd', 'baz', 'eggs',
'Z<boo <abv> foo>W', 'ttt', '<two<;>*<:> three>']
a<b<E1>c>d <b<E2>c>d <b<E3>c> a<<E4>c>d <<E5>>d <<E6>> <<>>
['a<b<E1>c>d', '<b<E2>c>d', '<b<E3>c>', 'a<<E4>c>d', '<<E5>>d',
'<<E6>>', '<<>>']
上記の文字列は整形式であり、結果は一貫しています。
整形式でないテキスト(角かっこに関して)では、望ましくない結果が生じる可能性があります。
ss = """A<B<C>D
E<F<G>H
I<J>K>
L<<M>N
O<P>>Q
R<<S> T<<>"""
print '\n\n%s\n' % ss
print reg.findall(ss)
結果
A<B<C>D
E<F<G>H
I<J>K>
L<<M>N
O<P>>Q
R<<S> T<<>
['E<F<G>H \nI<J>K>', 'L<<M>N\n O<P>>Q']
これは、の終わりにある星のせいです'(?:<[^<>]*?>[^<>]*)*'
。この動作は、星を削除することでオフにできます。この振る舞いは、Crtarooによって呼び出されるような「複雑な」テキストを分析するために正規表現を使用することを困難にするものです。
。
編集2
結果が望ましくないものであると言ったとき'E<F<G>H \nI<J>K>'
、'L<<M>N\n O<P>>Q'
それは、見つかった一致する部分が、私が作成した正規表現のパターン(どうしてそうなるのでしょうか?)を尊重していないという意味ではありませんでした。一致する部分は、確かに整形式です
。2つの部分は、2つのブラケットの間に<G>
あり、2
つの部分は、2つのブラケットの間にあります。<J>
< <G> <J> >
<M>
<P>
< <M> <P> >
実際、見つかった各一致部分は1行だけに拡張する必要があることを意味する控えめな表現でした。しかし、控えめな表現が明示されるとすぐに、可能な解決策が浮かび上がります。
複数の行にまたがる一致する部分が望ましくない場合は、私が書いたものとは逆に、それらを一致させないように正規表現に指示するのは簡単です。\n
正規表現のパターンのいくつかの場所に文字を追加するだけで十分です。
実際、これは、一致する部分が\n
文字を通過してはならないことを意味し、この文字は一致する部分の区切り文字と見なすことができます。#
したがって、たとえば次のコードでは 、同じ行に存在する一致する部分の間の区切り文字として、他の文字が必要になる場合があります。
。
正規表現は子供たちを料理したり学校から連れ出したりすることはできませんが、非常に強力です。不正な形式のテキストに対する正規表現の動作が問題であると言うのは短すぎます。正規表現ではなく、テキストの問題であると付け加える必要があります。正規表現は、指示されたとおりに実行します。つまり、正規表現に与えられたテキストをすべて食べます。そして、それは貪欲にそれを食べます。つまり、それについての適合性を確認せずに、それはそれからの意図された行動ではなく、それからそれが非食事的なテキストで供給された場合、それは責任を負いません。不正な形式のテキストに対する正規表現の動作が問題であると言うことは、誰かが子供にウイスキーや胡椒食品で栄養を与えられるように非難するかのように聞こえます。
正規表現に渡されるテキストが適切に形成されていることを確認するのは、コーダーの責任です。コーダーが検証スニペットをコードに入れて、プログラムが正しく実行されるようにエントリが整数であることを確認するのと同じ方法です。
。
この点は、マークアップされたテキストをXMLテキストとして解析しようとするときの正規表現の誤用とは異なります。不正な形式のマークアップされたテキストに正しく反応する正規表現を作成することは不可能であるため、正規表現はそのようなテキストを解析できません。それをやろうとしないのもコーダーの責任です。これは、このテキストが検証されている場合、マークアップされたテキストを分析するため
に正規表現を使用してはならないという意味ではありません。
とにかく、テキストがあまりにも奇形である場合、パーサーでさえデータをキャッチしません。
つまり、区別する必要があります。
。
import re
ss = """
A<:<11>:<12>:>
fgh
A<#:<33>:<34>:>
A#<:<55>:<56>:>
A<:<77>:<78> i<j>
A<B<C>D #
E<F<G>H #
I<J>K>
L<<M>N
O<P>>Q #
R<<S> T<<>"""
print '%s\n' % ss
pat = ('(?<!\S)' # absence of non-whitespace before
'(?:[^\s<>]*)'
'(?:<'
'[^<>]*?'
'(?:<[^<>]*?>[^<>]*)*'
'>)'
'(?:[^\s<>]*)'
'(?!\S)' # absence of non-whitespace after)
)
reg = re.compile(pat)
print '------------------------------'
print '\n'.join(map(repr,reg.findall(ss)))
pat = ('(?<!\S)' # absence of non-whitespace before
'(?:[^\s<>]*)'
'(?:<'
'[^<>\n]*?'
'(?:<[^<>\n]*?>[^<>\n]*)*'
'>)'
'(?:[^\s<>]*)'
'(?!\S)' # absence of non-whitespace after)
)
reg = re.compile(pat)
print '\n----------- with \\n -------------'
print '\n'.join(map(repr,reg.findall(ss)))
pat = ('(?<!\S)' # absence of non-whitespace before
'(?:[^\s<>]*)'
'(?:<'
'[^<>#]*?'
'(?:<[^<>#]*?>[^<>#]*)*'
'>)'
'(?:[^\s<>]*)'
'(?!\S)' # absence of non-whitespace after)
)
reg = re.compile(pat)
print '\n------------- with # -----------'
print '\n'.join(map(repr,reg.findall(ss)))
pat = ('(?<!\S)' # absence of non-whitespace before
'(?:[^\s<>#]*)'
'(?:<'
'[^<>#]*?'
'(?:<[^<>#]*?>[^<>#]*)*'
'>)'
'(?:[^\s<>]*)'
'(?!\S)' # absence of non-whitespace after)
)
reg = re.compile(pat)
print '\n------ with ^# everywhere -------'
print '\n'.join(map(repr,reg.findall(ss)))
結果
A<:<11>:<12>:>
fgh
A<#:<33>:<34>:>
A#<:<55>:<56>:>
A<:<77>:<78> i<j>
A<B<C>D #
E<F<G>H #
I<J>K>
L<<M>N
O<P>>Q #
R<<S> T<<>
------------------------------
'A<:<11>:<12>:>'
'A<#:<33>:<34>:>'
'A#<:<55>:<56>:>'
'i<j>'
'E<F<G>H #\n I<J>K>'
'L<<M>N \n O<P>>Q'
----------- with \n -------------
'A<:<11>:<12>:>'
'A<#:<33>:<34>:>'
'A#<:<55>:<56>:>'
'i<j>'
------------- with # -----------
'A<:<11>:<12>:>'
'A#<:<55>:<56>:>'
'i<j>'
'L<<M>N \n O<P>>Q'
------ with ^# everywhere -------
'A<:<11>:<12>:>'
'i<j>'
'L<<M>N \n O<P>>Q'