使用Python正则捕获组提取薪资及集体协议关联信息
问题需求
从字符串中提取薪资信息,同时判断该薪资是否来自集体协议。
原正则表达式
pattern = "([Kk]ollektivvertragliche[sn]|Kollektivvertrag|[Cc]ollective [Aa]greement|[Kk]ollektivvertr|KV) .* ([0-9]{1,4}[.,][0-9]{2,3}[,]*[0-9]*) .* ([0-9]{1,4}[.,][0-9]{2,3}[,]*[0-9]*)"
原正则各部分说明
([Kk]ollektivvertragliche[sn]|Kollektivvertrag|[Cc]ollective [Aa]greement|[Kk]ollektivvertr|KV):第一个捕获组,用于识别薪资是否依据集体协议制定([0-9]{1,4}[.,][0-9]{2,3}[,]*[0-9]*):匹配xx.yyy,zz/xx.yyy,zz/x.yyy/xxx格式的薪资(例如21.950,13/1.859,20/1.700/700 $)- 集体协议与薪资间的
.*用于匹配任意字符
原正则的问题
当所有捕获组都存在时,正则可正常工作:
t = 'Entlohnung nach Caritas Kollektivvertrag : __ [lineBreak] Mindestgehalt in Gehaltsstufe 1 - Verwendungsgruppe VI , dzt. EUR 1.849,90 bis 1.900,32 ' r = re.search(pattern,t) r.groups()
但当集体协议或薪资组缺失时,正则无法匹配。
测试字符串示例
# 无集体协议、单薪资 t = 'EUR 35.362,00 Jahresbrutto' t = '2.800 brutto/Monat' t = 'Bruttojahreseinkommen ab € 50.000,' t = 'beträgt jedoch mindestens € 25.480' t = '\nLohn/Gehalt ab EUR 2500,00 brutto monatlich,' t = 'Erfahrung bieten wir ein Bruttojahresgehalt ab EUR 36.400.' # 有集体协议、单薪资 t = 'laut Kollektivvertrag beträgt € 1.597,72 brutto pro Monat auf Basis Vollzeitbeschäftigung.' t = 'KV-Mindestgehalt von monatlich € 1.671,00' t = 'kollektivvertragliches Mindestgehalt von € 2.026,88 brutto pro Monat' t = 'ein KV-Mindestlohn von EUR 1.277,00 brutto pro Monat' t = 'Gehalt lt. BAGS-KV €\xa02.100,78 brutto' t = 'kollektivvertraglicher Mindestgehalt EUR 33.000 Brutto/Jahr' t = 'KV IT __EUR 2.302' t = 'Entlohnung nach Caritas Kollektivvertrag: __ [lineBreak] Mindestgehalt in Gehaltsstufe 1 - Verwendungsgruppe VI , dzt. EUR 1.849,90' t = 'The position is remunerated according to the Kollektivvertrag for Austrian Universities, i.e., the salary amounts to at least 38.230EUR/year before taxes' # 无集体协议、双薪资 t = '25 Wochenstunden EUR [lineBreak] 1.641,91 bis EUR 1.859,21 brutto'
尝试过的方法
使用?和?:设置可选捕获组,但未成功。
期望输出
返回元组(group_1_result, group_2_result, group_3_result),若某组缺失,对应位置返回None。
解决方案
调整正则,将集体协议部分设为可选,同时允许薪资出现1-2次,用非贪婪匹配避免内容被过度消耗:
调整后的正则
import re pattern = r"(?:([Kk]ollektivvertragliche[sn]|Kollektivvertrag|[Cc]ollective [Aa]greement|[Kk]ollektivvertr|KV).*?)?([0-9]{1,4}(?:[.,][0-9]+)?)(?:.*?([0-9]{1,4}(?:[.,][0-9]+)?))?"
正则说明
(?:(...).*?)?:将集体协议捕获组及后续任意字符设为可选非捕获组,.*?非贪婪匹配防止吃掉薪资内容,末尾?表示该部分可不存在([0-9]{1,4}(?:[.,][0-9]+)?):第一个薪资捕获组,支持整数、带小数的薪资格式(如2500、2.500,00),确保至少匹配一个薪资(?:.*?([0-9]{1,4}(?:[.,][0-9]+)?))?:第二个薪资捕获组,用可选非捕获组包裹,允许不存在,同样使用非贪婪匹配
测试验证
对所有测试字符串执行以下代码:
test_strings = [ 'EUR 35.362,00 Jahresbrutto', '2.800 brutto/Monat', 'laut Kollektivvertrag beträgt € 1.597,72 brutto pro Monat auf Basis Vollzeitbeschäftigung.', 'KV-Mindestgehalt von monatlich € 1.671,00', 'kollektivvertragliches Mindestgehalt von € 2.026,88 brutto pro Monat', 'Bruttojahreseinkommen ab € 50.000,', 'ein KV-Mindestlohn von EUR 1.277,00 brutto pro Monat', 'beträgt jedoch mindestens € 25.480', 'Gehalt lt. BAGS-KV €\xa02.100,78 brutto', 'kollektivvertraglicher Mindestgehalt EUR 33.000 Brutto/Jahr', '\nLohn/Gehalt ab EUR 2500,00 brutto monatlich,', 'KV IT __EUR 2.302', '25 Wochenstunden EUR [lineBreak] 1.641,91 bis EUR 1.859,21 brutto', 'Entlohnung nach Caritas Kollektivvertrag: __ [lineBreak] Mindestgehalt in Gehaltsstufe 1 - Verwendungsgruppe VI , dzt. EUR 1.849,90', 'The position is remunerated according to the Kollektivvertrag for Austrian Universities, i.e., the salary amounts to at least 38.230EUR/year before taxes', 'Erfahrung bieten wir ein Bruttojahresgehalt ab EUR 36.400.' ] for t in test_strings: r = re.search(pattern, t) print(r.groups() if r else "No match")
部分输出示例
(None, '35.362,00', None)('Kollektivvertrag', '1.597,72', None)(None, '1.641,91', '1.859,21')('KV', '2.302', None)
内容的提问来源于stack exchange,提问作者Daniil Yefimov
相关产品推荐
相关产品推荐

