【问题标题】:Python re.findall expected stringPython re.findall 预期字符串
【发布时间】:2021-12-26 14:50:15
【问题描述】:

我想用re.findall 在我的字符串中搜索一个词。代码如下:

def check_status():
   p1 = subprocess.run(["screen", "-ls"], shell=False)
   p2 = re.findall("myscreen", p1)
   print(p2)

p1 的返回如下所示:

There are screens on:
    2420454.myscreen        (12/25/2021 01:15:17 PM)        (Detached)
    6066.bot                (12/14/2021 07:11:52 PM)        (Detached)

如果我执行此函数,我会收到以下错误消息:

File "/usr/lib/python3.10/re.py", line 240, in findall
return _compile(pattern, flags).findall(string)
TypeError: expected string or bytes-like object

我已经搜索过这个问题,但一无所获。

我正在使用 Python 3.10

【问题讨论】:

  • 因为它需要一个字符串,你可以通过 str(p1)p1 转换为一个字符串
  • 如果我执行str(p1),该函数会返回一个空数组,如下所示:[]
  • 您可能需要在subprocess.run 上设置capture_output=True,然后查看p1.stdout 或使用其他subprocess 方法之一从命令中获取数据。

标签: python subprocess python-re gnu-screen findall


【解决方案1】:

subprocess.run 返回一个CompletedProcess 对象。您想将capture_output=Truetext=True 添加到关键字参数,并将正则表达式应用于其stdout 成员:

p2 = re.findall('myprocess', p1.stdout)

.. 当然,您不需要正则表达式来查找静态字符串:

p2 = 'myprocess' in p1.stdout

如果你想提取屏幕 ID,也许循环 stdout.splitlines() 并从匹配行中提取第一个标记。

p2 = []
for line in p1.stdout.splitlines():
    if 'myprocess' in line:
        p2.append(line.split('.')[0]

【讨论】:

  • 在您回答之前,我将subprocess.run 命令放在一个变量中。是一样的还是我的方式不太安全?
  • 我不明白。喜欢cmd = ['screen', '-ls']; p1 = subprocess.run(cmd)?从安全的角度来看,字面上没有区别,但无用的变量可能会冒犯敏感的眼睛(但不多)。
  • 我是这样使用的:p1 = subprocess.run(["screen", "-ls"], shell=False, stdout=subprocess.PIPE)p2 = ','.join(str(x) for x in re.findall(INSTANCE_NAME, str(p1)))
  • 我也看不到那里的安全隐患。您仍然不需要正则表达式,但如果您坚持使用正则表达式,则编译一次并将其放入变量中实际上可能对提高效率有意义。 str(p1) 看起来很不对;为什么不使用stdout 属性?
  • 我以前不知道,所以我会使用你的版本。如果您出于某种原因想 grep 进程名称,我的版本很好。我以前用它作为返回值。谢谢老哥
猜你喜欢
  • 2016-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多