2017-07-31 40 views
1

我想检查某个格式的字符串,如果匹配,则将值分配给字符串某些部分的变量。获取已知格式字符串的可变部分

例如字符串格式是'num_{month}_{year}_10p'而字符串是'num_october_16_10p'。我想将可变字符串部分({month}{year})分配给变量。我不知道提前确切字符串格式,所以我写了简单的功能:

function string(string, regexp, monthPart, yearPart) { 
    if(!(regexp instanceof RegExp) || !regexp.test(string)) { 
     return false; 
    } 

    // I know that delimiter is underscore 
    var parts = string.split('_'); 

    return { 
     month: parts[month], 
     year: parts[year] 
    }; 
} 

而且使用它像test('num_october_16_10p', /num_[a-z]{3,9}_[0-9]{2}_10p/, 1, 2);生成的正则表达式取决于形势。

有没有更好的方法来做到这一点?只使用正则表达式?以及如何支持任何字符串格式(根本没有特定的分隔符\ split())?

+0

是您的字符串总是NUM _?_?_ 10便士? –

+0

@AhmetCanGüven不可以,例如,它可以是''util_time_ {month} _ {year}''。 –

+0

因此,一个基本的reg表达式匹配'/ _([^ _] +)_([^ _] +)_ /'或带有月份名称和\ d {2}的年份 – epascarello

回答

1

这将适用于任何合理的分隔符和顺序,但期望月份名称可以是完整的英文名称或三个字母的缩写。年份可以是2位或4位数字。如果字符串中包含不止一个可能的匹配,只有第一个被认为是:

function extractDateParts(s) { 
 
    return { 
 
     month: (s.match(/([^a-z]|^)(jan(uary)?|feb(ruary?)|mar(ch?)|apr(il)?|may|june?|july?|aug(ust)?|sep(tember)?|oct(ober)?|nov(ember)?dec(ember)?)(?![a-z])/i) || [])[2], 
 
     year: +(s.match(/([^a-z0-9]|^)(\d\d(\d\d)?)(?![a-z0-9])/) || [])[2] || undefined 
 
    }; 
 
} 
 

 
console.log(extractDateParts('num_october_16_10p'));

1

您可以使用相同的正则表达式通过使用捕获组匹配和提取“可变字符串部分”。您可以通过在要捕获的令牌周围使用括号来创建捕获组。您可以修改您现有的正则表达式以匹配num_october_16_10p,如下所示:num_([a-z]{3,9})_([0-9]{2})_10p。然后,您可以用

import re 
regex = re.compile(r'num_([a-z]{3,9})_([0-9]{2})_10p') 
matches = regex.match('num_october_16_10p') 
matches.group(0) # 'num_october_16_10p' 
matches.group(1) # 'october' 
matches.group(2) # '16' 
matches.groups() # ('october', '16') 

使用它,因为你似乎是动态生成的正则表达式匹配,你应该能够添加捕获组。

+0

好的答案,但似乎你没有注意到问题是关于JS,而不是Python。 ;) –

0

它覆盖了所有的情况下

  • num_october_16_10p
  • util_time_october_17
  • october_17_10p_num

索引4将是月份,索引5将是年份。

const regex = /(_|(\w+|^))(_|^)(\w+)_(\d+)(_|$)/gm; 
 
const str = `num_october_16_10p 
 
util_time_october_17 
 
october_17_10p_num`; 
 
let m; 
 

 
while ((m = regex.exec(str)) !== null) { 
 
    // This is necessary to avoid infinite loops with zero-width matches 
 
    if (m.index === regex.lastIndex) { 
 
     regex.lastIndex++; 
 
    } 
 
    
 
    // The result can be accessed through the `m`-variable. 
 
    m.forEach((match, groupIndex) => { 
 
     console.log(`Found match, group ${groupIndex}: ${match}`); 
 
    }); 
 
}