我正在解析包含如下代码的字符串。它可以从一个空行开始,然后是多个可选模式。这些模式可以是python风格的内联注释(使用散列#字符),也可以是命令!我的命令”,两者都必须从一行的开头开始。我如何写一个正则表达式匹配到代码的开始?
mystring = """
# catch this comment
!mycommand
# catch this comment
#catch this comment too
!mycommand
# catch this comment
!mycommand
!mycommand
some code. match until the previous line
# do not catch this comment
!mycommand
# do not catch this comment
"""
import re
pattern = r'^\s*^#.*|!mycommand\s*'
m = re.search(pattern, mystring, re.MULTILINE)
mystring[m.start():m.end()]
mystring = 'code. do not match anything' + mystring
m = re.search(pattern, mystring, re.MULTILINE)
我希望正则表达式将字符串匹配到“some code.catch,直到前一行”。我尝试了不同的方法,但我可能被两种不同的模式困住了
无需重新安装。多行可以在匹配前后重复匹配0个空格字符
^(?:\s*(?:#.*|!mycommand\s*))+\s*
正则表达式演示| Python演示
例如
import re
m = re.search(r'^(?:\s*(?:#.*|!mycommand\s*))+\s*', mystring)
print(m.group())
您的模式匹配#...
或的一个实例!我的命令。解决这个问题的一个方法是将它们全部放入一个匹配中,并使用
re.search
查找第一个匹配。
为此,您需要重复匹配#...
或的部分!使用MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY-MY
^\s*^(?:#.*\s*|!mycommand\s*)*
我还更改了#*代码>到
#*\s*
这样它就一直到下一行,在那里可以找到非空白。
演示
回应您的评论:
如果字符串以代码开头,则此正则表达式不应匹配任何内容
你可以试试:
\A\s*^(?:#.*\s*|!mycommand\s*)+
我改为\A
,这样它只匹配字符串的绝对开头,而不是行的开头。我还将最后一个*
更改为,因此至少有一个
\代码>或
!mycommand必须存在。
匹配并返回字符串开头的注释
不需要正则表达式,读取并将这些行追加到列表中,直到一行不以开头出现代码>或
#
并忽略所有空行:
mystring = "YOUR_STRING_HERE"
results = []
for line in mystring.splitlines():
if not line.strip(): # Skip blank lines
continue
if not line.startswith('#') and not line.startswith('!'): # Reject if does not start with ! or #
break
else:
results.append(line) # Append comment
print(results)
请参阅Python演示。结果:
['# catch this comment', '!mycommand', '# catch this comment', '#catch this comment too', '!mycommand', '# catch this comment', '!mycommand', '!mycommand']
删除字符串开头的注释
results = []
flag = False
for line in mystring.splitlines():
if not flag and not line.strip():
continue
if not flag and not line.startswith('#') and not line.startswith('!'):
flag = True
if flag:
results.append(line)
print("\n".join(results))
输出:
some code. match until the previous line
# do not catch this comment
!mycommand
# do not catch this comment
请看这个Python演示。
正则表达式方法
import re
print(re.sub(r'^(?:(?:[!#].*)?\n)+', '', mystring))
如果行的开头有可选的缩进空格,请添加[^\S\n]*
:
print(re.sub(r'^(?:[^\S\n]*(?:[!#].*)?\n)+', '', mystring, count=1))
参见regex演示和Python演示。count=1
将确保我们只是删除第一个匹配(您不需要检查所有其他行)。
正则表达式详细信息
^
-字符串的开始(?:[^\S\n]*(?:[!#]。*)?\n)
-出现1个或多个
[^\S\n]*
-可选的水平空格(?:[!#]。*)?
-一个可选的序列
[!#]
-!
或#
.*
-行的其余部分