正则表达式python findall问题

时间:2016-10-14 21:11:53

标签: python regex

来自测试字符串:

 test=text-AB123-12a
 test=text-AB123a

我只需要提取'AB123-12''AB123',但是:

 re.findall("[A-Z]{0,9}\d{0,5}(?:-\d{0,2}a)?", test)

返回:

['', '', '', '', '', '', '', 'AB123-12a', '']

这些多余的空格是什么?如何删除它们?

5 个答案:

答案 0 :(得分:3)

量词{0,n}将匹配前一个模式的0到n次出现的任何位置。由于您匹配的两个模式允许0次出现,第三个模式是可选的(?),它将匹配0长度的字符串,即字符串中的每个字符。

为每个模式编辑以找到一个最小最大 9和5会产生正确的结果:

>>> test='text-AB123-12a'
>>> import re
>>> re.findall("[A-Z]{1,9}\d{1,5}(?:-\d{0,2}a)?", test)
['AB123-12a']

如果没有关于你所匹配的字符串的确切的详细信息,我无法给出更好的答案。

答案 1 :(得分:1)

您的模式设置为匹配零长度字符,并将字符集量词的下限设置为0.只需设置为1即可生成所需的结果:

    /* Donor Schema */
    var DonorSchema = new Schema({
     _id : {type: Number},
     Name: { type: String, required: true },
     DOB: { type: Date, required: true, trim: true },
     Sex: { type: String },
     BloodGroupID: { type: Schema.Types.ObjectId, ref: 'BloodGroup', required: true },  
     ContactNo: { type: String, required: true },
     LocationId: { type: Schema.Types.ObjectId, ref: 'Location', required:true },
     EmailId: { type: String, required: true },
     Password: { type: String, required: true }
    });


    /* bloodGroup Schema */
   var bloodGroupSchema = new Schema({
       _bid :{ type: Number, ref: 'Donor' },
       name: { type: String, required: true }
   });


    module.exports = mongoose.model('Donor', DonorSchema);
    module.exports = mongoose.model('Blood', bloodGroupSchema);


    var vidya = new Donor({ _id: 0, name: 'Vidya', sex: 'F' }); 
        vidya.save(function (err) {
          if (err) return handleError(err);

          var blood = new BloodGroup({
            name: 'B+',
            _bid: vidya._id    // assign the _id from the Donor
          });

          blood.save(function (err) {
            if (err) return handleError(err);
            // thats it!
          });
        });

答案 2 :(得分:0)

RegEx测试人员:http://www.regexpal.com/表示您的模式字符串[A-Z]{0,9}\d{0,5}(?:-\d{0,2}a)?可以匹配0个字符,因此无限匹配。

再次检查你的表情。 Python为您提供了未定义的结果。

答案 3 :(得分:0)

由于模式的所有部分都是可选的(您的范围指定到N次出现并且您使用?来限定组),因此字符串中的每个位置都算作匹配项其中大多数是空的。

如何防止这种情况发生取决于您要匹配的确切格式。你的比赛的所有部分都是可选的吗?

答案 4 :(得分:0)

由于字母或数字在开头是可选的,因此您必须确保至少有一个字母或一个数字,否则您的模式将匹配字符串中每个位置的空字符串。你可以用一个先行的方式开始你的模式。例如:

re.findall(r'(?=[A-Z0-9])[A-Z]{0,9}\d{0,5}(?:-\d\d?)?(?=a)', test)

通过这种方式,比赛可以以字母或数字开头。

我假设当有连字符时,后面跟着至少一个数字(否则这个连字符的原因是什么?)。换句话说,我认为最后不可能-a。 (如果我错了,请纠正我。)

为了从匹配结果中排除“a”,我把它推到了前瞻。