0

次のテキストがあります。

ERROR: <C:\Includes\Library1.inc:123> This is the Error
Call Trace:
    <C:\Includes\Library2.inc:456>
    <C:\Includes\Library2.inc:789>
    <C:\Code\Main.ext:12> 
    <Line:1> 
ERROR: <C:\Includes\Library2.inc:2282> Another Error
Call Trace:
    <C:\Code\Main.ext:34>
    <C:\Code\Main.ext:56>
    <C:\Code\Main.ext:78>
    <Line:1> 
ERROR: <C:\Code\Main.ext:90> Error Three

以下の情報を抽出したいと思います。

line, Error = 12, This is the Error
line, Error = 34, Another Error
line, Error = 90, Error Three

これが私が得た距離です:

theText = 'ERROR: ...'
ERROR_RE = re.compile(r'^ERROR: <(?P<path>.*):(?P<line>[0-9]+)> (?P<error>.*)$')
mainName = '\Main.ext'
# Go through each line
for fullline in theText.splitlines():
    match = self.ERROR_RE.match(fullline)
    if match:
        path, line, error = match.group('path'), match.group('line'), match.group('error')
        if path.endswith(mainName):
            callSomething(line, error)
        # else check next line for 'Call Trace:'
        # check next lines for mainName and get the linenumber
        # callSomething(linenumber, error)

ループ内の残りの要素をループするpythonicの方法は何ですか?

解決策: http://codepad.org/BcYmybin

4

2 に答える 2

1

残りの行をループする方法に関する質問への直接的な答えは、ループの最初の行を次のように変更することです。

lines = theText.splitlines()
for (linenum, fullline) in enumerate(lines):

次に、試合の後、次の試合まで開始して実行lines[j]される内側のループを調べることで、残りの行を取得できます。jlinenum+1

ただし、この問題を解決するよりスマートな方法は、最初にテキストをブロックに分割することです。これを行うには多くの方法がありますが、以前の perl ユーザーである私の衝動は、正規表現を使用することです。

# Split into blocks that start with /^ERROR/ and run until either the next
# /^ERROR/ or until the end of the string.
#
# (?m)      - lets '^' and '$' match the beginning/end of each line
# (?s)      - lets '.' match newlines
# ^ERROR    - triggers the beginning of the match
# .*?       - grab characters in a non-greedy way, stopping when the following
#             expression matches
# (?=^ERROR|$(?!\n)) - match until the next /^ERROR/ or the end of string
# $(?!\n)   - match end of string.  Normally '$' suffices but since we turned
#             on multiline mode with '(?m)' we have to use '(?!\n)$ to prevent
#             this from matching end-of-line.
blocks = re.findall('(?ms)^ERROR.*?(?=^ERROR|$(?!\n))', theText)
于 2013-06-27T13:26:14.937 に答える