在一行中某个符号第 n 次出现后匹配数字

matching numbers after nth occurence of a certain symbol in a line

我不确定在这里使用正则表达式是否是解决此问题的正确方法,但我想先尝试用正则表达式解决这个问题(如果可能的话)

我有一个 edifact 文件,其中某些段的某些字段中的数据(粗体)需要替换(日期不同,格式相同)

UNA:+,? '  
UNB+UNOC:3+000000000+000000000+20190801:1115+00001+DDMP190001'  
UNH+00001+BRKE:01+00+0'    
INV+ED Format 1+Brustkrebs+19880117+E000000001+**20080702**+++1+0'       
FAL+087897044+0000000++name+000000000+0+**20080702**++1+++J+N+N+N+N+N+++0'   
INL+181095200+385762115+++0'   
BEE+20080702++++0'   
BAA+++J+J++++++J+++++++J++0'   
BBA++++++++J++++++J+J++++++J+++++J+++J+J++++++++J+0'   
BHP+J+++++J+++++J+++++0'   
BLA+++J+++++++++0'   
BFA++++++++++++J++0'   
BSA++J+++J+J+++0'    
BAT+20190801+0'    
DAT+**20080702**++++0'   
UNT+000014+00001'   
UNZ+00001+00001'   

起初我能够使用正向前瞻和后视来匹配这些字段(我有不同的表达式来匹配每个日期)。

例如,我最初用来匹配"FAL"段中的日期的表达式:(?<=\+[\d]{1}\+)\d{8}(?=\+\+),但后来我看到这个日期有时前面有9位数字,有时1(基于版本)然后是 ++ 或 + 和日期所以我添加了一个 logiacl OR 像这样:(?<=\+[\d]{9}\+|\+[\d]{1}\+)\d{8}(?=\+[\d]{8}\+|\+\+) 并很快意识到它是不可持续的,因为我看到这些 edifact 文件各不相同(远仅超过 9 位和 1 位数字)

(每种我有6个版本,一共6个)

因为我有一个 scheme/map 指示每个版本应该构建成什么样,而且我知道每个版本中日期写在什么位置(基于 + 分隔符),所以我考虑过可能匹配日期基于+,所以在某行加号第7次出现(比如在FAL段)之后,匹配接下来的8位数字。

这可以用正则表达式实现吗?如果是,有人可以告诉我怎么做吗?

我建议使用像

这样的模式
^((?:[^+\n]*\+){7})\d{8}(?=\+(?:\d{8})?\+)

其中{7}可以调整为您需要的每个类型段的值,并替换为对组1的反向引用。在Python中,它是\g<1>20200101(其中20200101 是你的新日期),在 PHP/.NET 中,它是 20200101。在 JS 中,它只是 </code>.</p> <p>要在多行文本上 运行,请使用 <code>m 标志。在 Python 正则表达式中,您可以像 (?m)^((?:[^+\n]*\+){7})\d{8}(?=\+(?:\d{8})?\+).

一样嵌入它

Python regex demo

详情

  • ^ - string/line
  • 的开始
  • ((?:[^+\n]*\+){7}) - 第 1 组:7 次重复 + 和换行符以外的任何字符,然后是 +
  • \d{8} - 8 位数
  • (?=\+(?:\d{8})?\+) - 后跟 +,以及可选的 8 位数字块和 +.