-2

对于我正在处理的这个问题,我需要指出正确的方向:

假设我正在读取 C 程序的输出,如下所示:

while True:
    ln = p.stdout.readline()
    if '' == ln:
        break
    #do stuff here with ln

我的输出看起来像这一行:

TrnIq: Thread on CPU 37
TrnIq: Thread on CPU 37 but will be moved to CPU 44
IP-Thread on CPU 33
FANOUT Thread on CPU 37
Filter-Thread on CPU 38 but will be moved to CPU 51
TRN TMR Test 2 Supervisor Thread on CPU 34
HomographyWarp Traking Thread[0] on CPU 26

我想将“TrnIq:Thread on”和“37”捕获为两个单独的变量:一个字符串和一个来自输出“TrnIq:Thread on CPU 37”的数字。

对于其他行而言,它非常相似,例如从“HomographyWarp Traking Thread[0] on CPU 26”捕获“HomographyWarp Traking Thread[0] on”和#“26”。

唯一真正的挑战是这样的行:“CPU 38 上的过滤器线程,但将移动到 CPU 51”在这一行我需要“Filer-Thread”和#“51”而不是第一个 #“38”。

Python 有很多不同的方法可以做到这一点,我什至不知道从哪里开始!

提前致谢!

4

5 回答 5

4

以下应该返回一个信息元组,假设ln是单行数据(编辑以包括将 CPU 值转换为 int):

match = re.match(r'(.*?)(?: on CPU.*)?(?: (?:on|to) CPU )(.*)', ln).groups()
if match:
    proc, cpu = match.groups()
    cpu = int(cpu)

例子:

>>> import re
>>> for ln in lines:
...     print re.match(r'(.*?)(?: on CPU.*)?(?: (?:on|to) CPU )(.*)', ln).groups()
... 
('TrnIq: Thread', '37')
('TrnIq: Thread', '44')
('IP-Thread', '33')
('FANOUT Thread', '37')
('Filter-Thread', '51')
('TRN TMR Test 2 Supervisor Thread', '34')
('HomographyWarp Traking Thread[0]', '26')

解释:

(.*?)          # capture zero or more characters at the start of the string,
               #   as few characters as possible
(?: on CPU.*)? # optionally match ' on CPU' followed by any number of characters,
               #   do not capture this
(?: (?:on|to) CPU )  # match ' on CPU ' or ' to CPU ', but don't capture
(.*)           # capture the rest of the line

rubular:http ://www.rubular.com/r/HqS9nGdmbM

于 2012-07-20T16:53:03.443 回答
2

正则表达式在这里对我来说似乎有点矫枉过正。[免责声明:我不喜欢正则表达式,但喜欢 Python,所以我尽可能用 Python 编写,而不是编写正则表达式。由于我从未完全理解的原因,这被认为是令人惊讶的。]

s = """TrnIq: Thread on CPU 37
TrnIq: Thread on CPU 37 but will be moved to CPU 44
IP-Thread on CPU 33
FANOUT Thread on CPU 37
Filter-Thread on CPU 38 but will be moved to CPU 51
TRN TMR Test 2 Supervisor Thread on CPU 34
HomographyWarp Traking Thread[0] on CPU 26"""

for line in s.splitlines():
    words = line.split()
    if not ("CPU" in words and "on" in words): continue # skip uninteresting lines
    prefix_words = words[:words.index("on")+1]
    prefix = ' '.join(prefix_words)
    cpu = int(words[-1])
    print (prefix, cpu)

('TrnIq: Thread on', 37)
('TrnIq: Thread on', 44)
('IP-Thread on', 33)
('FANOUT Thread on', 37)
('Filter-Thread on', 51)
('TRN TMR Test 2 Supervisor Thread on', 34)
('HomographyWarp Traking Thread[0] on', 26)

而且我认为我不需要将任何代码翻译成英文。

于 2012-07-20T17:08:10.357 回答
1

所以使用正则表达式^(.*?)\s+on\s+CPU.*(?<=\sCPU)\s+(\d+)\s*$

import sys
import re

for ln in sys.stdin:
  m = re.match(r'^(.*?)\s+on\s+CPU.*(?<=\sCPU)\s+(\d+)\s*$', ln); 
  if m is not None:
    print m.groups();

在此处查看并测试示例。

于 2012-07-20T16:54:26.920 回答
1

在您提到的情况下,您总是需要第二个 CPU 编号,因此可以使用单个正则表达式来完成:

# Test program
import re

lns = [
    "TrnIq: Thread on CPU 37",
    "TrnIq: Thread on CPU 37 but will be moved to CPU 44",
    "IP-Thread on CPU 33",
    "FANOUT Thread on CPU 37",
    "Filter-Thread on CPU 38 but will be moved to CPU 51",
    "TRN TMR Test 2 Supervisor Thread on CPU 34",
    "HomographyWarp Traking Thread[0] on CPU 26"
]

for ln in lns:
    test    = re.search("(?P<process>.*Thread\S* on).* CPU (?P<cpu>\d+)$", ln)
    print "%s: '%s' on CPU #%s" % ( ln, test.group('process'), test.group('cpu'))

在一般情况下,您可能想要区分不同的情况(例如 CPU 上的线程、移动的线程、子线程......)。为此,您可以一个接一个地使用多个 re.search()。例如:

# This search recognizes lines of the form "...Thread on CPU so-and-so", and
# also lines that add "...but will be moved to CPU some-other-cpu".
test = re.search("(?P<process>.* Thread) on CPU (?P<cpu1>\d+)( but will be moved to CPU (?P<cpu2>\d+))*", ln)
if test:
   # Here we capture Process Thread, both moved and non moved
   if test.group('cpu2'):
       # We have process, cpu1 and cpu2: moved thread
   else:
       # Nonmoved task, we have test.group('process') and cpu1.
else:
   # No match, try some other regexp. For example processes with a thread number
   # between square brackets: "Thread[0]", which are not captured by the regex above.
   test = re.search("(?P<process>.*) Thread[(?P<thread>\d+)] on CPU (?P<cpu1>)", ln)
   if test:
       # Here we have Homography Traking in process, 0 in thread, 26 in cpu1

为了获得最佳性能,最好先对出现频率更高的线路进行测试。

于 2012-07-20T16:55:26.670 回答
1

它可以通过两个正则表达式搜索非常简单地完成:

import re

while True:
    ln = p.stdout.readline()
    if '' == ln:
        break

    start_match = re.search(r'^(.*?) on', ln)
    end_match = re.search(r'(\d+)$', ln)
    process = start_match and start_match.group(0)
    process_number = end_match and end_match.group(0)
于 2012-07-20T17:00:06.293 回答