正则表达式 - 在必填前缀和可选组之间收集字符

时间:2017-06-27 18:30:14

标签: javascript regex

我在JavaScript中创建正则表达式,找到所有组的出现,都是可选的。

我现在收集了可选组(感谢@wiktor-stribiżew)。缺少的是在new-前缀和第一个发生的组之间收集字符。

输入:

new-rooms-3-area-50
new-poland-warsaw-rooms-3-area-50-bar
new-some-important-location-rooms-3-asdads-anything-area-50-uiop
new-another-location-area-50-else

请求的输出:

["rooms-3", "area-50"]
["poland-warsaw", "rooms-3", "area-50"]
["some-important-location", "rooms-3", "area-50"]
["another-location", "area-50"]

我现在

new-(?:.*?(rooms-\d+))?.*?(area-\d+)

正则表达式。我认为在.*new-之间收集rooms|area可能是愚蠢的解决方案。

在线演示:https://regex101.com/r/QvmYN0/5

注意:我创建了两个独立的问题,因为它引用了2个单独的问题。我希望将来有人会遇到类似的问题。

3 个答案:

答案 0 :(得分:2)

我认为最好按照以下步骤进行分割:

// Split by \n to work with each line
getArrays = input => input.split`\n`.map(x => {

  // Split by your desired delimiters:
  // -dashes which has "area" or "rooms" in front
  return x.split(/-(?=area-|rooms-)/g).map(y => {

    // remove the "new-" from start or anything in front the numbers
    return y.replace(/^new-|\D+$/, '');

  // make sure you don't have empty cases
  }).filter(y => y);

});

var txt = `new-rooms-3-area-50
new-poland-warsaw-rooms-3-area-50-bar
new-some-important-location-rooms-3-asdads-anything-area-50-uiop
new-another-location-area-50-else`;

console.log(getArrays(txt));

修改 上面的代码返回请求的输出。但是,我认为你应该想要一组模型:

// initial state of your model
getModel = () => ({
  new: '',
  area: 0,
  rooms: 0,
});

// the function that will return the array of models:
getModels = input => input.split`\n`.map(line => {
  var model = getModel();
  
  // set delimiters:
  var delimiters = new RegExp(
    '-(?=(?:' + Object.keys(model).join`|` + ')-)', 'g');
  
  // set the properties of your model:
  line.split(delimiters).forEach(item => {
    
    // remove non-digits after the last digit:
    item.replace(/(\d)\D+$/, '$1')
    
      // set each matched property:
      .replace(/^([^-]+)-(.*)/, 
        (whole_match, key, val) => model[key] = val);
  });
  
  return model;
});

var txt = `new-rooms-3-area-50
new-poland-warsaw-rooms-3-area-50-bar
new-some-important-location-rooms-3-asdads-anything-area-50-uiop
new-another-location-area-50-else`;

console.log(getModels(txt));

答案 1 :(得分:1)

这是高端解决方案,可以同时完成所有工作 不分割或按摩数据,只需按原样(并且始终如此) 它可能不适合初学者,但适合经验丰富的人士。

请注意,我不知道JS,但我可以告诉你,这花了大约20分钟 谷歌搜索字符串。这太简单了,人们真的得到了报酬 这样做?!

这使用exec来推送每个元素(组2)
并创建一个记录数组,每行一个。

    ( ^ new )                     # (1)
 |  
    (                             # (2 start)
         (?: rooms | area )
         - \d+ 
      |  (?:
              (?:
                   (?!
                        (?: rooms | area )
                        - \d+ 
                   )
                   [a-z] 
              )+
              (?:
                   -
                   (?:
                        (?!
                             (?: rooms | area )
                             - \d+ 
                        )
                        [a-z] 
                   )+
              )+
         )
    )                             # (2 end)

var strTarget = "\
new-rooms-3-area-50\n\
new-poland-warsaw-rooms-3-area-50-bar\n\
new-some-important-location-rooms-3-asdads-anything-area-50-uiop\n\
new-another-location-area-50-else\n\
";

var RxLine = /^new.+/mg;
var RxRecord = /(^new)|((?:rooms|area)-\d+|(?:(?:(?!(?:rooms|area)-\d+)[a-z])+(?:-(?:(?!(?:rooms|area)-\d+)[a-z])+)+))/g;

var records = [];
var matches
var match;

while( (match = RxLine.exec( strTarget )) ){
    var line = match[0];
    matches = [];
    while( (match = RxRecord.exec( line )) ){
        if ( match[2] )
            matches.push( match[2] );
    }
    records.push( matches );
}
     
console.log( records );

答案 2 :(得分:0)

你走了: boost::uniform_int<>::operator()

演示:https://regex101.com/r/Qvdkdx/1