带有多文件测试用例的字符串的正则表达式

2024-10-02 02:43:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图为可能产生不同格式的字符串找出一个特定的正则表达式:

例如:

"Fluid 13.4"

"Fluid 13.4 gm% fluid_haemo 12.0-14.0"

"Fluid gm% 13.4 fluid_haemo 12.0-14.0"

"Fluid gm% fluid_hameo 12.0-14.0 13.4"

"fluid fluid fluid 13.4"

"fluid rex cell (FRC) 13.4"

"Fluid rex cell 1800"

我的实际需求有点棘手:

  1. 我想要字符串中第一个单词的“流体”或任何东西

  2. 数字“13.4”或在某些情况下,它可能不是十进制

  3. 如果字符串中有连续的单词,后跟小数或数字

    字符串1:“流体,13.4”编辑

    管柱2:“流体13.4”

    管柱3:“流体13.4”

    管柱4:流体13.4“

    管柱5:“流体13.4”

    串6:“流体rex电池(FRC)13.4”

    串7:“流体rex电池1800”

我所尝试的:

[a-zA-Z].* \d.*\.+\d.*

[a-zA-Z].* [\d.]+ (?=[a-z%\/])

但由于明显的原因,我的正则表达式非常区分大小写,我不知道字符串的格式

有没有任何方法或正则表达式可以解决这样的问题


Tags: 字符串电池格式cell数字单词frcrex
3条回答

看起来您的输入总是有Fluid,然后后面的第一个数字就是您想要的数字。如果是这样的话,你可以用

Fluid\b.*?(\d*\.?\d*)

这将匹配文本Fluid,后跟一个“边界”字符,然后跳过它可以跳过的最小字符数,直到找到尽可能多的十进制数字字符,一个可选的小数点后跟尽可能多的十进制字符

这当然是特定于您的案例的,并且依赖于Fluid始终存在

在上一种情况下,它将匹配12.0而不是13.4

你可以用

\b([a-zA-Z]+)(?: [a-zA-Z]+%.*?)? (\d+(?:\.\d+)?)(?!\S)
  • \b防止部分匹配的单词边界
  • ([a-zA-Z]+)捕获组1,匹配1+char a-zA-Z
  • (?: [a-zA-Z]+%.*?)? 可选地匹配空格和字符a-z,后跟%和空格
  • (\d+(?:\.\d+)?)捕获第2组,将1+个数字与可选的小数部分匹配
  • (?!\S)在右边声明一个空白边界

Regex demo

import re

strings = [
    "Fluid 13.4",
    "Fluid 13.4 gm% fluid_haemo 12.0-14.0",
    "Fluid gm% 13.4 fluid_haemo 12.0-14.0",
    "Fluid gm% fluid_hameo 12.0-14.0 13.4"
]
pattern=r"\b([a-zA-Z]+)(?: [a-zA-Z]+%.*?)? (\d+(?:\.\d+)?)(?!\S)"
for s in strings:
    print(re.findall(pattern, s))

输出

[('Fluid', '13.4')]
[('Fluid', '13.4')]
[('Fluid', '13.4')]
[('Fluid', '13.4')]

编辑

要捕获第一组中包含的“单词”,您可以选择包含重复匹配的空格,后跟1+倍的任何允许字符,这些字符以右边的whitspace边界结尾

\b([A-Za-z]+\b(?:\s+[\w()]+)*(?!\S)).*?\s(\d+(?:\.\d+)?)(?!\S)
  • \b防止部分匹配的单词边界
  • (捕获组1
    • [A-Za-z]+\b匹配1+字符A-Za-z和单词边界
    • (?:\s+[\w()]+)*可选地重复空格字符,后跟字符类中任何允许字符的1+倍
    • (?!\S)在右边声明一个空白边界
  • )关闭组1
  • .*?\s匹配尽可能少的字符,然后再匹配一个空白字符
  • (捕获第2组
    • \d+(?:\.\d+)?
  • )关闭组2
  • (?!\S)在右边声明一个空白边界

Regex demo

你可以用

import re
rx = r'\b([A-Za-z]+)\b.*?\s(\d+(?:\.\d+)?)(?!\S)'
texts = ["Fluid 13.4","Fluid 13.4 gm% fluid_haemo 12.0-14.0","Fluid gm% 13.4 fluid_haemo 12.0-14.0","Fluid gm% fluid_hameo 12.0-14.0 13.4"]
for text in texts:
    match = re.search(rx, text)
    if match:
        print(text, '=>', f'{match.group(1)} {match.group(2)}')

# => Fluid 13.4 => Fluid 13.4
#    Fluid 13.4 gm% fluid_haemo 12.0-14.0 => Fluid 13.4
#    Fluid gm% 13.4 fluid_haemo 12.0-14.0 => Fluid 13.4
#    Fluid gm% fluid_hameo 12.0-14.0 13.4 => Fluid 13.4

Python demoregex demo

详细信息

  • \b-单词边界
  • ([A-Za-z]+)-第1组:ASCII字母单词
  • \b-单词边界
  • .*?-除换行符以外的任何零个或多个字符,尽可能少
  • \s-一个空格
  • (\d+(?:\.\d+)?)-第2组:一个或多个数字,然后是一个.和一个或多个数字的可选序列
  • (?!\S)-右侧空白边界

相关问题 更多 >

    热门问题