regex Python正则表达式字母拆分

d5vmydt9  于 2023-08-08  发布在  Python
关注(0)|答案(3)|浏览(97)

我有两个字符串:

'''N678 N−12.,13.12.22,18.,19.,31.1.,9.2.,7. au 10.,13. au 17.,20.,21.,22.,28.
au 31.3.,6.,13.,19.,20.4.,5.,8.5.23'''

'''N678 à p. du 11.6.23 C+23.6.23 N−14.,24.7.23'''

字符串
我想这样分割:应用于第二个字符串:

['N678 à p. du 11.6.23 ', 'C+23.6.23 ', 'N−14.,24.7.23']


其概念是:每次你看到格式:any_character\s\d{1,2}.\d{1,2}.\d{2,4}\s[A-Z]拆分它。我用这个正则表达式做了最后一个例子:([A-Za-z].*?\d{1,2}\.\d{1,2}\.\d{2,4}\s*)但它不适用于第一个,因为N678 N-12.会在Au附近分裂

`['N678 N−12.,13.12.22', 'au 10.,13. au 17.,20.,21.,22.,28.\nau 31.3.,6.,13.,19.,20.4.,5.,8.5.23']`


如果我删除可选的匹配问号,它将在第一个字符串中正常工作,但这将导致第二个字符串的结果不正确。
有什么想法吗?

kyvafyod

kyvafyod1#

将正则表达式更新为

([A-Z].*?\d{1,2}\.\d{1,2}\.\d{2,4}\s*[^A-Z]*)

字符串
这至少在给定的情况下是有效的。

import re

regex = '([A-Z].*?\d{1,2}\.\d{1,2}\.\d{2,4}\s*[^A-Z]*)'

strings = [
    '''N678 N-12.,13.12.22,18.,19.,31.1.,9.2.,7. au 10.,13. au 17.,20.,21.,22.,28. au 31.3.,6.,13.,19.,20.4.,5.,8.5.23''',
    '''N678 à p. du 11.6.23 C+23.6.23 N-14.,24.7.23'''
]

for string in strings:
    print(re.findall(regex, string))


输出量:

['N678 N-12.,13.12.22,18.,19.,31.1.,9.2.,7. au 10.,13. au 17.,20.,21.,22.,28. au 31.3.,6.,13.,19.,20.4.,5.,8.5.23']
['N678 à p. du 11.6.23 ', 'C+23.6.23 ', 'N-14.,24.7.23']

q8l4jmvw

q8l4jmvw2#

你需要在一个look-ahead上分裂:

(?=[A-Z][+−-]?\d+\b)

字符串
https://regex101.com/r/hoyJ9q/1
请注意,“N−14”中的“破折号”不是标准破折号。
JS参考示例:

var regexp = /(?=[A-Z][+−-]?\d+\b)/g;

var str = 'N678 à p. du 11.6.23 C+23.6.23 N−14.,24.7.23';

console.log(str.split(regexp));

var str = 'N678 N−12.,13.12.22,18.,19.,31.1.,9.2.,7. au 10.,13. au 17.,20.,21.,22.,28. au 31.3.,6.,13.,19.,20.4.,5.,8.5.23';

console.log(str.split(regexp));

zxlwwiss

zxlwwiss3#

如果你只想在第二个字符串中找到匹配,你可以匹配而不是分割。

\b[A-Z].*?\d{1,2}\.\d{1,2}\.\d{2,4}(?=\s+[A-Z]|$)

字符串
模式匹配:

  • \b防止部分字匹配的字边界
  • [A-Z]匹配一个大写字符A-Z(因为所有匹配似乎都以一开头)
  • .*?匹配任何字符,尽可能少
  • \d{1,2}\.\d{1,2}\.\d{2,4}匹配您的“digits`模式
  • (?=\s+[A-Z]|$)正向预测,Assert1+空格字符,后跟右边的字符A-Z,或者Assert字符串的结尾。* (注意\s也可以匹配换行符)*

Regex demo|Python demo

import re

pattern = r"\b[A-Z].*?\d{1,2}\.\d{1,2}\.\d{2,4}(?=\s+[A-Z]|$)"

s = ("N678 à p. du 11.6.23 C+23.6.23 N−14.,24.7.23\n\n"
    "N678 N−12.,13.12.22,18.,19.,31.1.,9.2.,7. au 10.,13. au 17.,20.,21.,22.,28.\n"
    "au 31.3.,6.,13.,19.,20.4.,5.,8.5.23\n\n"
    "N68 du 12.6. au 3.9.23 C+23.6.,15.8.23 N-18.,25.6.,2.,17. au 21.,23. au 28.,31.7.,3.,4.,7.,8.,9.,27.8.23\n\n\n")

print(re.findall(pattern, s, re.M))


产出

[
  'N678 à p. du 11.6.23', 'C+23.6.23', 'N−14.,24.7.23', 'N68 du 12.6. au 3.9.23', 'C+23.6.,15.8.23',
  'N-18.,25.6.,2.,17. au 21.,23. au 28.,31.7.,3.,4.,7.,8.,9.,27.8.23'
]

注意,如果.*?后面没有直接跟\s+[A-Z]\d{1,2}\.\d{1,2}\.\d{2,4}也可以匹配此格式

如果你不想这样,你可以使用tempered greedy token

\b[A-Z](?:(?!\d{1,2}\.\d{1,2}\.\d{2,4}\b).)*\d{1,2}\.\d{1,2}\.\d{2,4}(?=\s+[A-Z]|$)


Regex demo

相关问题