Pythonソースコードを解析していて、一重引用符と二重引用符で囲まれた文字列の正規表現があります(このスレッドに対するridgerunnerの回答を読んで取得)。
single_quote_re = "'([^'\\\\]*(?:\\\\.[^'\\\\]*)*)'";
double_quote_re = '"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"';
現在、Pythonの複数行の文字列(3つの二重引用符)を処理しようとしています。
s = '"""string one\'s end isn\'t here; \\""" it\'s here """ """string two here"""'
# correct output for findall should be:
# ['string one\'s end isn\'t here; \\""" it\'s here ','string two here']
少しいじってみましたが、それでも正しくありません。
multiline_string_re = '"""([^(""")\\\\]*(?:\\\\.[^(""")\\\\]*)*)"""'
直前に円記号が付いていない(つまり、最初の二重引用符がエスケープされていない)「」を言う方法が必要です。
編集:私は近づく必要があります。私は以下を試しました:
r'(?<!\\)""".*(?<!\\)"""'
# Matches the entire string; not what I'm going for.
r'(?<!\\)"""[^((?<!\\)""")](?<!\\)"""'
# Matches that space between the two strings ('""" """') in the sample string s (see code above, prior to edit).
r'(?<!\\)"""([^((?<!\\)""")]*(?:\\.[^((?<!\\)""")]*)*)(?<!\\)"""'
# Same result as before, but with the triple quotes shaved off (' ').
# Note: I do indeed want the triple quotes excluded.
更新: slnのおかげで、解決策は "" "[^" \\] (?:(?:\\。| "")[^ "\\] )*" ""の ように見えます
multiline_string_re = '"""[^"\\\\]*(?:(?:\\\\.|"")[^"\\\\]*)*"""'
re.findall(multiline_string_re, s, re.DOTALL)
# Result:
# ['"""string one\'s end isn\'t here; \\""" it\'s here """', '"""string two here"""']
更新されたソリューション、slnのおかげで:
multiline_single_re = "'''[^'\\\\]*(?:(?:\\\\.|'{1,2}(?!'))[^'\\\\]*)*'''"
multiline_double_re = '"""[^"\\\\]*(?:(?:\\\\.|"{1,2}(?!"))[^"\\\\]*)*"""'
これは、Perlで正規表現を使用したテストケースです。エスケープ
された二重引用符フォーム ""だけでなく、エスケープされたものも許可する
場合は、サイトに配置した正規表現の1つを変更して、二重引用符を許可します。
一重引用符をエスケープすると、ソース文字列が削除されます。
use strict;
use warnings;
$/ = undef;
my $str = <DATA>;
while ($str =~ /"[^"\\]*(?:(?:\\.|"")[^"\\]*)*"/sg )
{
print "found $&\n";
}
__DATA__
"""string one's end isn't here; \""" it's here """ """string two here"""
出力>>
found """string one's end isn't here; \""" it's here """
found """string two here"""
有効性とエラー処理のために、正規表現には
、whileループの本体で処理できるパススルー構造(代替)が含まれている必要があることに注意してください。
例/"[^"\\]*(?:(?:\\.|"")[^"\\]*)*"|(.)/sg
、
次に
while(){
//グループ1に一致し、空白ではない場合=エラーの可能性
}
追加-コメントへの返信。
Pythonブロックリテラルに関するいくつかの調査の後、
エスケープ文字だけでなく
、本文で最大2つの二重引用符を処理する必要があるようです。つまり、"
または""
正規表現を変更するのは簡単です。1-2の数量詞を追加し、先読みアサーションで抑制します。
以下は、選択して選択できる生の正規表現パーツと文字列の正規表現パーツです。
Perlでテストされ、動作します。
がんばろう!
# Raw -
# (?s:
# """[^"\\]*(?:(?:\\.|"{1,2}(?!"))[^"\\]*)*"""
# |
# '''[^'\\]*(?:(?:\\.|'{1,2}(?!'))[^'\\]*)*'''
# )
# String'd -
# '(?s:'
# '"""[^"\\\]*(?:(?:\\\.|"{1,2}(?!"))[^"\\\]*)*"""'
# '|'
# "'''[^'\\\\]*(?:(?:\\\\.|'{1,2}(?!'))[^'\\\\]*)*'''"
# ')'
(?s: # Dot-All
# double quote literal block
""" # """ block open
[^"\\]* # 0 - many non " nor \
(?: # Grp start
(?:
\\ . # Escape anything
| # or
"{1,2} # 1 - 2 "
(?! " ) # Not followed by a "
)
[^"\\]* # 0 - many non " nor \
)* # Grp end, 0 - many times
""" # """ block close
| # OR,
# single quote literal block
''' # ''' block open
[^'\\]* # 0 - many non ' nor \
(?: # Grp start
(?:
\\ . # Escape anything
| # or
'{1,2} # 1 - 2 '
(?! ' ) # Not followed by a '
)
[^'\\]* # 0 - many non ' nor \
)* # Grp end, 0 - many times
''' # ''' block close
)
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加