繁体   English   中英

用正则表达式或常规Python进行字符串替换?

[英]String substitution with regex or regular Python?

我有如下字符串列表

orig = ["a1  2.3  ABC  4  DEFG  567  b890",
        "a2  3.0  HI  4  5  JKL  67  c65",
        "b1  1.2  MNOP  3  45  67  89  QR  987  d64  e112"]

这里的上下文是这是一个CSV文件,某些列被省略。 我认为熊猫csv阅读器无法处理这些情况。 现在的想法是为缺少的值注入na ,因此输出变为

corr = ["a1  2.3  ABC  4  na  na  na  DEFG  567  b890",
        "a2  3.0  HI  4  5  na  na  JKL  67  c65",
        "b1  1.2  MNOP  3  45  67  89  QR  987  d64  e112"]

稍后在以熊猫输入时将第二列与大写字母对齐。

结构如下:列之间的分隔符是两个或多个空格,两个大写列之间的分隔符必须是四个值。 在原始文件中,总是只有两个大写字母列,它们之间至少有一个数字,最多有四个数字,并且这些大写字母之间只有数字值。
我可以毫无问题地用本机Python编写脚本,因此请不要提出任何建议。 但是我认为,这可能是正则表达式的例子。 作为一个正则表达式初学者,我仅设法通过以下方式提取了两个大写列之间的字符串:

for line in orig:
    a = re.findall("([A-Z]+[\s\d]+[A-Z]+)", line))
    print(a)
>>>'ABC  4  DEFG' #etc pp

正则表达式中现在是否有一种简单的方法来确定大写单词之间有多少个数字,并插入“ na”值以始终保持四个值? 还是应该在本机Python中执行此操作?

当然,如果有一种方法可以使用熊猫csv阅读器来做到这一点,那就更好了。 但是我研究了熊猫csv_reader文档 ,但没有发现任何有用的东西。

基于完整的熊猫方法,拆分和合并可能会有所帮助,即

ndf = pd.Series(orig).str.split(expand=True)

#   0    1     2  3     4    5     6     7     8     9     10
#0  a1  2.3   ABC  4  DEFG  567  b890  None  None  None  None
#1  a2  3.0    HI  4     5  JKL    67   c65  None  None  None
#2  b1  1.2  MNOP  3    45   67    89    QR   987   d64  e112

df = pd.concat([ndf.iloc[:,:4], ndf.iloc[:,4:].apply(sorted,key=pd.notnull,axis=1)],1)

df.astype(str).apply(' '.join,axis=1).tolist()

['a1 2.3 ABC 4 None None None None DEFG 567 b890',
 'a2 3.0 HI 4 None None None 5 JKL 67 c65',
 'b1 1.2 MNOP 3 45 67 89 QR 987 d64 e112']

尽管人们普遍认为正则表达式不是进行这种动态字符串替换的最佳工具,但我发现re模块在这种情况下使用起来相当舒适。 捕获模式基于Jon Clements的评论。

import re

orig = ["a1  2.3  ABC  4  DEFG  567  b890",
        "a2  3.0  HI  4  5  JKL  67  c65",
        "b1  1.2  MNOP  3  45  67  89  QR  987  d64  e112"]

corr = []

for item in orig:
    #capture group starting with first capitalised word and stopping before the second
    col_betw = re.search("\s{2,}([A-Z]+.*)\s{2,}[A-Z]+\s{2,}", item).group(1)
    #determine, how many elements we have in this segment
    nr_col_betw = len(re.split(r"\s{2,}", col_betw))
    #substitute, if not enough numbers
    if nr_col_betw <= 4:
        #fill with NA, which is interpreted by pandas csv reader as NaN
        subst = col_betw + "   NA" * (5 - nr_col_betw) 
        item = item.replace(col_betw, subst, 1)
    corr.append(item)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM