将特殊标识符模式替换为回复sub在python中

2024-06-02 07:48:28 发布

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

我是regex新手,在re.sub中有一个regex替代品,我想不通。你知道吗

import re

test_cases = [
    "1-Some String #0123",
    "2-Some String #1234-56-a",
    "3-Some String #1234-56A ",
    "4-Some String (Fubar/ #12-345-67A)",
    "5-Some String (Fubar - #12-345.67 A)",
    "6-Some String / #123",
    "7-Some String/#0233",
    "8-Some #1 String/#0233"
    ]

for test in test_cases:
    test = re.sub(r'[/|#][A-Z|a-z|0-9|-]*','', test)
    print(test)

代码应打印:

1-Some String
2-Some String
3-Some String
4-Some String (Fubar)
5-Some String (Fubar)
6-Some String
7-Some String   
8-Some #1 String   

但是,我现在得到的是(4,5,8没有完全转换):

1-Some String 
2-Some String 
3-Some String  
4-Some String (Fubar )
5-Some String (Fubar - .67 A)
6-Some String  
7-Some String
8-Some  String

Tags: 代码intestimportre替代品forstring
3条回答

分两步进行可能更容易:

第一:清理括号中的部分。在“(”和一些字母后面删除所有直到结尾的内容“)”。你知道吗

第二:去掉一行末尾不需要的东西。行以“#”结尾,后跟2个或更多数字或“/”。“#”或“/”前面可能有空格。你知道吗

import re

paren_re = re.compile(r"([(][a-zA-Z]+)([^)]*)")

eol_re = re.compile(r"(.*?)\s*(?:#\d\d|/).*")

for line in test_cases:
    result = paren_re.sub(r"\1", line)
    result = eol_re.sub(r"\1", result)

    print(result)

请尝试以下操作:

import re

test_cases = [
    "1-Some String #0123",
    "2-Some String #1234-56-a",
    "3-Some String #1234-56A ",
    "4-Some String (Fubar/ #12-345-67A)",
    "5-Some String (Fubar - #12-345.67 A)",
    "6-Some String / #123",
    "7-Some String/#0233",
    "8-Some #1 String/#0233"
    ]

for test in test_cases:
    test = re.sub(r'\s*([/#]|- )[\sA-Za-z0-9-#\.]*(?=(\)|$))','', test)
    print(test)

结果:

1-Some String
2-Some String
3-Some String
4-Some String (Fubar)
5-Some String (Fubar)
6-Some String
7-Some String
8-Some #1 String

regex(要删除的子字符串)可以定义为:

  • 以“/”、“#”或“-”开头
  • 前面可以有空格
  • 由空格、字母数字、连字符、哈希或点组成
  • 通过“行尾”或“)”锚定,使用正向展望

那么正则表达式将如下所示: \s*([/#]|- )[\sA-Za-z0-9-#\.]*(?=(\)|$))

positive lookahead可能需要一些解释。模式(?=regex) 是一个零宽度断言,表示followed by regex。 好处是匹配的子串不包括regex和 您可以将它用作anchor。你知道吗

另一种选择是使用负的lookahead(?![^#\n\r]*#)只匹配最后出现的#。为了清楚起见,我在方括号之间加了一个空格[ ]。你知道吗

[ ]*(?:[/-][ ]*)?#(?![^#\n\r]*#)[\da-zA-Z. -]+

解释

  • [ ]*匹配0+次空格
  • (?:[/-][ ]*)?可选地匹配/-和0+空间
  • #逐字匹配
  • (?![^#\n\r]*#)负向前看,当右边的is om不包含#时断言
  • [\da-zA-Z. -]+匹配character类中列出的1+倍

Regex demo

在替换中使用空字符串。你知道吗

相关问题 更多 >