regex 我需要帮助制作一个棘手的正则表达式

8yoxcaq7  于 2023-08-08  发布在  其他
关注(0)|答案(2)|浏览(63)

我正在尝试编写一些Python代码,用于解析一些使用'#'字符开始注解的文本文件。我正在寻找一种方法来删除尾随注解从一行的文件。
一开始我尝试了str.rfind('#'),但这还不够,因为有些文件的注解以"##"开头,或者有多个注解(例如:#comment1 #comment2)。
接下来,我尝试了几种re.sub的组合来删除它们,但遇到了一些问题,文件中的行包含字符串中的注解字符(例如:"attempt #3")。
在这些文件中,与C一样,字符串文字用双引号括起来,字符文字用单引号括起来。
我正在寻找的是一种方法,在Python中,当注解字符位于单引号或双引号内时,可以从行中删除尾随注解,而不会打扰它们。
以下是导致我出现问题的线路示例,我需要一个全面的解决方案:

variable_name  ## sometimes used  ## variable:L"name####":

variable_name = "Update Gen11 E5 ROM version to 1.34_04_25_2023 (#24201)"

file_name  #comment1 #comment2

字符串
这些的输出应为:

variable_name

variable_name = "Update Gen11 E5 ROM version to 1.34_04_25_2023 (#24201)"

file_name


在第一种情况下,引号内的'#'被视为注解的一部分,并被删除,因为之前有一个不在引号内的'#'
在第二种情况下,'#'在引号内,并且没有前面的'#',因此该行保持不变。
在最后一种情况下,该行从第一个注解开始被剥离,因为'#'是最左边的,不在引号内。

p5fdfcr1

p5fdfcr11#

你可以在sub()中使用这个正则表达式。替换为\1组1。

\#.*|("(?:\\[\S\s]|[^"\\])*"|'(?:\\[\S\s]|[^'\\])*'|[\S\s][^"'#]*)

字符串
https://regex101.com/r/UhyIwd/1
解释

\# .*                            # Comment all until end of line
 |                                 # or,
    (                                # (1 start), Non - comments 
         "
         (?: \\ [\S\s] | [^"\\] )*        # Double quoted text
         "
      |  '
         (?: \\ [\S\s] | [^'\\] )*        # Single quoted text
         ' 
      |  [\S\s]                           # Any other char
         [^"'#]*                          # Chars which doesn't start a comment, string
    )                                # (1 end)


代码示例

import re

pattern = r"""\#.*|("(?:\\[\S\s]|[^"\\])*"|'(?:\\[\S\s]|[^'\\])*'|[\S\s][^"'#]*)"""

target = '''
variable_name  ## sometimes used  ## variable:L"name####":
variable_name = "Update Gen11 E5 ROM version to 1.34_04_25_2023 (#24201)"
file_name  #comment1 #comment2
'''

res = re.sub( pattern, r'\1', target)
print(res)


产出

variable_name
variable_name = "Update Gen11 E5 ROM version to 1.34_04_25_2023 (#24201)"
file_name

iyfjxgzm

iyfjxgzm2#

据我所知,注解以第一个散列标记('#',又名磅符号,octothorpe)开始,该散列标记不在括号表达式中。
您可以将以下正则表达式的匹配项转换为空字符串,前提是您确信始终会有偶数个双引号:

\ *#[^\"]*(?:(?:\"[^\"]*\")[^\"]*)*$

字符串
Demo
这个想法是,'#'福尔斯括号表达式,当且仅当它和字符串的结尾之间有奇数个双引号。
注意,我已经将链接中的每个[^\"]更改为[^\"\n],以便可以显示多个示例的结果。我转义了正则表达式开头的空格字符,只是为了表明它存在。
正则表达式具有以下元素。

\ *#          match zero or more spaces then '#'
[^\"]*        match zero or more chars other than dbl quotes
(?:           begin outer non-capture group
  (?:         begin inner non-capture group
    \"        match dbl quote
    [^\"]*    match zero or more chars other than dbl quotes
    \"        match dbl quote
  )           end inner non-capture group
  [^\"]*      match zero or more chars other than dbl quotes
  )*          end outer non-capture group and execute >= 0 times
$

相关问题