Py学习  »  Wiktor Stribiżew  »  全部回复
回复总数  7
4 年前
回复了 Wiktor Stribiżew 创建的主题 » Python正则表达式,带行开头的多行搜索

你可以用

re.sub(r'^ABC(?:\nABC)*$', 'TEST', text, flags=re.M)

看到了吗 regex demo . 细节 :

  • ^ -一行的开始(由于 re.M )
  • ABC -固定字符串
  • (?:\nABC)* -LF字符的零次或多次重复,以及 基础知识 一串
  • $ -行尾。

注意 flags=re.M 需要配合使用 flags= 由于中的下一个位置属性 re.sub 输入字符串之后是 计数 属性

7 年前
回复了 Wiktor Stribiżew 创建的主题 » 如何克服regex标志设置(Python)的问题?

因为字典中的键是小写的,所以您应该将匹配项转换为小写:

s = pattern.sub(lambda x: abbreviationsDict()[x.group(1).lower()] + ' ', s)
                                                        ^^^^^^^^ 

见 Python demo :

import re
def abbreviationsDict():
    return {'ref.': 'reference', 'ref:': 'reference', 'approx.': 'approximately', 'no.': '', 'nos.': ''}
pattern = re.compile(r'\b({})(?!\w)'.format('|'.join(re.escape(key) for key in abbreviationsDict().keys())), flags=re.I)
s = "Variation of Condition on planning application Ref: CB/15/03633/FULL dated 30/11/2015: Condition 9"
s = pattern.sub(lambda x: abbreviationsDict()[x.group(1).lower()], s)
print(s)
# => Variation of Condition on planning application reference CB/15/03633/FULL dated 30/11/2015: Condition 9

请注意 \W 在模式的末尾,使用任何非单词字符,并用空格替换它。我建议你转身 \西 变成一个 (?!\w) 并放弃附加 " " 在lambda表达式中。

7 年前
回复了 Wiktor Stribiżew 创建的主题 » python regex替换所有以“:”开头的单词,下一个字符是字母

根据您的要求,您可以使用

s = re.sub(r'\B:([^\W\d_]\w*)', r'${\1}', s)

见 regex demo .

细节

  • \B: -一个 : 前面没有单词char(或在字符串开头)
  • ([^\W\d_]\w*) -第一组( \1 在替换模式中):
    • [^\W\d_] -任何 信
    • \w* -任何0+字母、数字、下划线。

注意:如果您只想匹配ASCII字母和数字,并且您使用的是Python 3.x,请使用 re.A 或 re.ASCII 标志:

s = re.sub(r'\B:([^\W\d_]\w*)', r'${\1}', s, flags=re.A)

Python demo :

import re
s = "select  ... from (\r\nselect  ... from ( \r\nselect  ... from  table1\r\nwhere session_started between  toDateTime(:DatumOd) and toDateTime(:DatumDo)\r\nand session_id in (select distinct ...  from table2\r\n    where   session_start>=toDateTime('2019-01-01 10:11:12') and session_module=:channel\r\n            and session_start between  toDateTime(:DatumOd) and toDateTime(:DatumDo)\r\n            and ( domain_name in (:domain) or 'All domains' in (:domain) )\r\n            and (technology in (:technology) or 'All' in (:technology))\r\n            and (CASE when session_principal_role='Self care' then agent_name else session_principal_role end in  (:application) \r\n            or 'All' in (:application) )  )\r\norder by session_id desc , execution_id desc, step_started desc, step_id desc)\r\n) where step_type=:step_type and ..."
s = re.sub(r'\B:([^\W\d_]\w*)', r'${\1}', s, flags=re.A)
print(s)

输出:

select  ... from (
select  ... from ( 
select  ... from  table1
where session_started between  toDateTime(${DatumOd}) and toDateTime(${DatumDo})
and session_id in (select distinct ...  from table2
    where   session_start>=toDateTime('2019-01-01 10:11:12') and session_module=${channel}
            and session_start between  toDateTime(${DatumOd}) and toDateTime(${DatumDo})
            and ( domain_name in (${domain}) or 'All domains' in (${domain}) )
            and (technology in (${technology}) or 'All' in (${technology}))
            and (CASE when session_principal_role='Self care' then agent_name else session_principal_role end in  (${application}) 
            or 'All' in (${application}) )  )
order by session_id desc , execution_id desc, step_started desc, step_id desc)
) where step_type=${step_type} and ...
7 年前
回复了 Wiktor Stribiżew 创建的主题 » 如何修复python中的“re.error:unterminated character set at position”?

在符合ECMAscript的正则表达式中(正则表达式可能是为该正则表达式引擎编写的), [^] 用于匹配任何字符,它是一个有效的字符类,它匹配“除零以外的任何内容”,因此匹配所有内容。

你应该使用 [\s\S]*? 在这里而不是 [^]+ 尽可能少地匹配任何0+字符。

8 年前
回复了 Wiktor Stribiżew 创建的主题 » python中的正则表达式lookahead[重复]

这里有两件事要注意:

  • re.findall 如果regex模式中包含捕获组,则返回捕获的文本
  • 这个 r'\\.' 模式中的部分匹配两个连续字符, \ 以及换行符以外的任何字符。

见 findall reference :

如果模式中存在一个或多个组,则返回一个组列表;如果模式有多个组,则返回一个元组列表。空匹配将包含在结果中,除非它们触及另一个匹配的开头。

注意 使 芬德尔 只返回匹配值 ,您通常可以

  • 删除冗余捕获组(例如 (a(b)c) -gt; abc )
  • 将所有捕获组转换为 non-capturing (即,替换 ( 具有 (?: ) 除非 有引用模式中的组值的反向引用(请参见下文)
  • 使用 re.finditer 而不是( [x.group() for x in re.finditer(pattern, s)] )

对你来说, 芬德尔 返回所有捕获的空文本,因为 \\ 在内部 r'' 试图匹配文本的字符串文本 \ .

要匹配这些数字,您需要使用

-?\d*\.?\d+

regex匹配:

  • -? -可选减号
  • \d* -可选数字
  • \.? -可选小数分隔符
  • \d+ -一个或多个数字。

见 demo

这里是 IDEONE demo :

import re
s = r'abc123d, hello 3.1415926, this is my book'
pattern = r'-?\d*\.?\d+'
L = re.findall(pattern, s)
print(L)
7 年前
回复了 Wiktor Stribiżew 创建的主题 » 正则表达式与python 3中以下划线开头和结尾的单词匹配

如果您要匹配任何字符块(字母、数字和下划线),而这些字符块的前面或后面没有非单词字符(字母、数字和下划线以外的字符)和任何长度(甚至是1, _ )你可以用

r'\b_(?:\w*_)?\b'

具有 re.findall . 见 regex demo .

如果不想匹配单字符单词(即 γ )您需要删除可选的非捕获组,并使用 r'\b_\w*_\b' .

如果需要匹配至少3个字符的单词,也可以替换 * (零次或多次重复) + (一次或多次发生)。

如果仅当单词位于字符串的开头/结尾或后跟/前面有空格时才将其视为完整单词,请替换 \b...\b 具有 (?<!\S)...(?!\S) :

r'(?<!\S)_\w*_(?!\S)'

见 another regex demo

细节

  • \b -一个字的边界,必须有一个字符串的开头或一个非字的字符
  • γ -下划线
  • (?:\w*_)? -一个可选的非捕获组,与
    • \w* -0+字字符(字母、数字, γ (感谢这个可选的组,甚至 γ 将找到单词)
    • γ -下划线
  • \b -单词边界,后面必须有字符串结尾或非单词字符
  • (?<!\S) -左空白边界
  • (?!\S) -右空白边界

见 Python demo :

rx = re.compile(r'\b_(?:\w*_)?\b')
print(rx.findall(test_str))
# => ['_text_', '__text__']
7 年前
回复了 Wiktor Stribiżew 创建的主题 » 在python中,在匹配字符串的特定模式之后获取数字

你可以用

(?<!\w)(your|escaped|keywords|here)\W*([A-Z]*\d+(?:-+[A-Z]*\d+)*)

见 regex demo .

图案细节

  • (?<!\w) -左字边界(明确, \b 意思是上下文相关的,如果下一个字符是非单词字符,它需要在左边有一个单词字符,这不是用户通常期望的)
  • (your|escaped|keywords|here) -捕获组1:您的关键字列表,可以使用 '|'.join(map(re.escape,my_list)) (音符 re.escape 必须转义特殊的regex元字符,如 . , + , ( , [ 等)
  • \W* -0+非字字符(除字母、数字或 _ )
  • ([A-Z]*\d+(?:-+[A-Z]*\d+)*) -捕捉组2:
    • [A-Z]* -零个或多个大写ASCII字母
    • \d+ -一个或多个数字
    • (?:-+[A-Z]*\d+)* -0次或多次重复
      • -+ -一个或多个连字符
      • [A-Z]*\d+ -零个或多个大写ASCII字母,1个或多个数字

见 Python demo :

import re
s="""your_text_here"""
my_list = ['Ref.:', 'Reference', 'tramite', 'Expediente', 'Expediente No', 'Expedien N°', 'Exp.No', 'Expedien']
rx = r'(?<!\w)({})\W*([A-Z]*\d+(?:-+[A-Z]*\d+)*)'.format('|'.join(map(re.escape,my_list)))
print(re.findall(rx, s))

输出:

[('Expedien', '1-21-212-16-26'), ('Reference', 'RE9833'), ('tramite', '1234567'), ('Expedien N°', '18-00777'), ('Expedien N°', '18-0022995')]