Tworzę REGEX w JavaScript, który znajdzie wszystkie zdarzenia grupowe, wszystkie opcjonalne.

Zebrałem opcjonalne grupy (dzięki za @ Wiktor-StribiżeW) teraz. Brakujące rzeczy to gromadzenie znaki między prefiksem new- i pierwszą grupą.

Wejście:

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

Żądana wyjście:

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

Mam teraz

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

Regex. Myślę, że zbieranie .* między new- i rooms|area może być głupie rozwiązanie.

Demo online: https://regex101.com/r/qvmyn0/5

Uwaga: Stworzyłem dwa oddzielne pytania, ponieważ odnosi się do 2 problemów oddzielnie. Mam nadzieję, że ktoś miał podobne problemy w przyszłości.

0
Mateusz Jagiełło 27 czerwiec 2017, 21:30

3 odpowiedzi

Najlepsza odpowiedź

Myślę, że lepiej podzielić według takich kroków:

// 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));

Edytuj: Powyższy kod zwraca żądaną wyjście. Myślałem jednak, że zamiast tego powinieneś mieć szereg modeli:

// 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));
2
Washington Guedes 27 czerwiec 2017, 20:18

Proszę bardzo: new-(.*?)?-?(rooms-\d+|area-\d+).*?(area-\d+)?.*

Demo: https://regex101.com/r/qvdkdx/1

0
DanielR 27 czerwiec 2017, 19:10

Jest to roztwór wysokiej klasy, który robi wszystko na raz.
Nie dzieli ani nie masaż danych, po prostu bierze go tak, jak jest (i zawsze będzie).
Może nie być dla początkujących, ale bądź dla bardziej doświadczonych.

( Należy pamiętać, że nie wiem JS, ale mogę ci powiedzieć, zajęło to około 20 minut
Googling o ciągach. To jest po prostu łatwe, czy ludzie naprawdę otrzymują płatne
zrobić to?!
)

Wykorzystuje to Exec, aby nacisnąć każdy element (grupa 2)
i stworzyć tablicę rekordów, jeden dla każdej linii.

    ( ^ 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 );
1
27 czerwiec 2017, 21:29