一个文本文件中,内容如下:(注:横线上方我标记的是位置。)
123456...... 30 31 32 33 ......
------------------------------------------------------------------------------------------------
AA山田 花1 1234 aaa
AA山田 下夫12 1111 aaa
AA山田 下夫1 1212 aaa
AA山田 下夫123 2323 aaa
AA山田 下夫12 8888 aaa
......
......
......
我的目的是:
检查半角的第30位开始的连续4位不全是数字的查找出来,于是我用了这个正则:^.{29}(?!\d{4})
但是因为第3位开始是全角的日文姓名再加一些全角的数字,而正则中的“.”匹配的是半角或全角,在匹配全角字符时,正则会当成1个字符,但实际它占了2个半角的位置,就导致“.{29}”匹配之后实际的位置就到了第32、33位之后。
我想直接用一个正则表达式来解决这个问题,因为就是在文本文件中,不想利用编程解决。
我自己的一些思考:
正则中是否有只匹配位置的功能?如果有的话,我就只忽略前29个半角位置,可能就能解决这个问题。
想请教朋友们,非常感谢!
不管全角还是半角,对于正则来说,都是一个字符,他不会计算这个字符到底是几位组成的
另外, 既然你已经要用正则了,就不要局限于索引位置了,局限索引位置,是字符串方法,不是正则方法
import re
a = '''AA山田 花1 1234 aaa
AA山田 下夫12 1111 aaa
AA山田 下夫1 1212 aaa
AA山田 下夫123 2323 aaa
AA山田 下夫12 8888 aaa'''
# 不能是四个数字
print(re.findall(r'(?:^|\n)([^\s]+)\s+([^\s]+)\s+((?!\d{4})[^\s]+)\s+([^\s]+)',a))
不能是四个相同数字
print(re.findall(r'(?:^|\n)([^\s]+)\s+([^\s]+)\s+((?!(\d)\4{3})[^\s]+)\s+([^\s]+)',a))
import re
a = '''
\nAA山田 花1 1234 aaa\n
\nAA山田 下夫12 1111 aaa\n
\nAA山田 下夫1 1212 aaa\n
\nAA山田 下夫123 2323 aaa\n
\nAA山田 下夫12 888a bbbb\n
'''
# 4位非空白字符
print(re.findall(r'(?:^|\n)([\S]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)', a))
# 4位不全是数字的空白字符
print(re.findall(r'(?:^|\n)([\S]+)\s+([\S]+)\s+((?!(\d){4})[\S]+)\s+([\S]+)', a))
?: 表示一个非捕获分组,即这个分组匹配的内容不会被捕获到分组中。在正则表达式中,通常用 () 来表示一个捕获分组,用于捕获匹配的内容。但有时我们并不需要捕获匹配的内容,只是想把一些模式放在一起作为一个整体来匹配或排除一些内容,这时就可以使用非捕获分组来实现。r'(?:^|\n)' 表示一个非捕获分组。这个分组包含两个可能的匹配项:一是字符串的开头(^),二是换行符(\n)。
([\S]+)\s+
[\S]+ 匹配1个或者一个以上的非空字符
([\S]+)这些非空字符被分组,需要被记住,也就是被我抓取
\s+ 匹配1个或者1个以后上的任意空白字符
((?!(\d){4})[\S]+)
最外层的()表示这是一个分组
(\d){4} 表示4个数字
(?!(\d){4}) 表示不是4个数字