正则表达式提取字符串

3
我需要帮助使用正则表达式从字符串中提取以下内容。
dal001.caxxxxx.test.com. ---> caxxxxx.test.com
caxxxx.test.com -----> caxxxx.test.com

基本上,在第一个例子中,我不想要 dal001 或任何以 3 个字母和 3 个数字开头的字符串,如果它以 ca 开头,我只想要其余的字符串。

在第二个例子中,我想要以 ca 开头的整个字符串。

到目前为止,我尝试过 (^[a-z]{3}[\d]+\.)?(ca.*),但当字符串是 dal001.mycaxxxx.test.com 时它无法正常工作。

任何帮助将不胜感激。


1
ca.*$ 对你有效吗? - Keldan Chapman
将第一组转换为非捕获组,^(?:[a-z]{3}\d{3}\.)?(ca.*),值将在第1组中。请参见https://regex101.com/r/mL8mkG/1和https://ideone.com/hS6lz5。 - Wiktor Stribiżew
1
@WiktorStribiżew,它运行得非常好。谢谢你。 - developthou
3个回答

2

您可以使用

^(?:[a-z]{3}\d{3}\.)?(ca.*)

请查看正则表达式演示。要使其不区分大小写,请使用re.I编译(re.search(rx, s, re.I),请参见下文)。

详细信息

  • ^ - 字符串的开头
  • (?:[a-z]{3}\d{3}\.)? - 三个字母和三个数字以及一个.的可选序列
  • (ca.*) - 第1组:ca和其余字符串。

请参阅Python演示

import re
rx = r"^(?:[a-z]{3}\d{3}\.)?(ca.*)"
strs = ["dal001.caxxxxx.test.com","caxxxx.test.com"]
for s in strs:
  m = re.search(rx, s)
  if m:
    print( m.group(1) )

1
这个工作真的很好。非常感谢你。 - developthou
唯一的问题是当有一个不匹配的字符串时,它会失败。In [13]: re.search(r"^(?:[a-z]{3}\d{3}\.)?(ca.*)",'10.9.65.35').group(1) --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) in () ----> 1 re.search(r"^(?:[a-z]{3}\d{3}\.)?(ca.*)",'10.9.65.35').group(1) AttributeError: 'NoneType' object has no attribute 'group'有没有一种方法可以忽略不匹配的字符串而不使用try? - developthou
1
@developthou 在访问.group()之前,一定要先检查是否有匹配项。我已经在答案中展示了如何做,你没有使用我的代码。 - Wiktor Stribiżew
我正在使用列表推导式 当没有匹配时,返回[re.search(r"^(?:[a-z]{3}\d{3}.)?(ca.*)",host).group(1) for host in hosts]无效。 - developthou
我认为在这种情况下不应该使用列表推导。 - developthou
显示剩余4条评论

0

使用 re.sub 如下:

import re
strs = ['dal001.caxxxxx.test.com', 'caxxxx.test.com']

for s in strs:
    s = re.sub(r'^[A-Za-z]{3}\d{3}[.]', '', s)
    print(s)
# caxxxxx.test.com
# caxxxx.test.com

2
谢谢,但是如果只匹配ca,它将无法提取字符串。 - developthou

0

如果你正在使用re

import re
my_strings = ['dal001.caxxxxx.test.com', 'caxxxxx.test.com']
my_regex = r'^(?:[a-zA-Z]{3}[0-9]{3}\.)?(ca.*)'
compiled_regex = re.compile(r)
for a_string in my_strings:
    if compiled_regex.match(a_string):
        compiled_regex.sub(r'\1', a_string)

my_regex 匹配以 [3个字母][3个数字][一个 .] 开头的字符串(^ 锚定在字符串的开头),但是只是可选的,并且使用非捕获组((?:) 不会得到一个编号引用来在 sub 中使用)。无论哪种情况,它都必须包含 ca,后面跟着任何内容,这部分将作为调用 re.sub 时的替换。如果您有许多要匹配的字符串,则使用 re.compile 可以使其更快。

关于 re.compile 的说明: 有些答案在循环之前不费心地预编译正则表达式。他们做出了一项交易:以删除单个代码行为代价,隐含地在每次迭代中重新编译正则表达式。如果您将在循环体中使用正则表达式,则应始终首先对其进行编译。这样做对程序的速度可以产生重大影响,即使迭代次数很少也不会增加额外成本。这里有一个编译和非编译版本使用相同的正则表达式执行相同的循环,并针对不同数量的循环迭代和试验次数进行比较。你自己来评判。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接