2016-11-03 7 views
1

должен иметь разделенные запятые строки текста, где каждый текст имеет или нет - запятую - маркер в списке, какКак сопоставить текст с маркером выражением с/без отрицательного предпросмотра в JavaScript Regex

var tokens=['Inc.','Ltd','LLC']; 

так струна как

var companies="Apple, Inc., Microsoft, Inc., Buzzfeed, Treasure, LLC"; 

Я хочу, чтобы получить этот массив в качестве выходного

var companiesList = [ 
    "Apple Inc.", 
    "Microsoft Inc.", 
    "Buzzfeed", 
    "Treasure LLC" 
    ]; 

Так что, во-первых сделал RegExp как тот

var regex=new RegExp("([a-zA-Z&/? ]*),\\s+("+token+")", "gi") 

, что я получаю спички и искать регулярное выражение, как

var regex=new RegExp("([a-zA-Z&/? ]*),\\s+("+item+")", "i") 

для каждой из лексем:

tokens.forEach((item) => { 
    var regex = new RegExp("([a-zA-Z&/? ]*),\\s+(" + item + ")", "gi") 
    var matches = companies.match(regex) || [] 
    console.log(item, regex.toString(), matches) 
    matches.forEach((m) => { 
     var regex = new RegExp("([a-zA-Z&/? ]*),\\s+(" + item + ")", "i") 
     var match = m.match(regex) 
     if (match && match.length > 2) { 
      var n = match[1].trim(); 
      var c = match[2].trim(); 
      companiesList.push(n + ' ' + c); 
     } 
    }); 
}); 

Таким образом, Я могу захватить маркеры и согласованные группы 1 и 2.

var tokens = ['inc.', 'ltd', 'llc'], 
 
    companies = "Apple, Inc., Microsoft, Inc., Buzzfeed, Treasure, LLC", 
 
    companiesList = []; 
 
tokens.forEach((item) => { 
 
    var regex = new RegExp("([a-zA-Z&/? ]*),\\s+(" + item + ")", "gi") 
 
    var matches = companies.match(regex) || [] 
 
    console.log(item, regex.toString(), matches) 
 
    matches.forEach((m) => { 
 
    var regex = new RegExp("([a-zA-Z&/? ]*),\\s+(" + item + ")", "i") 
 
    var match = m.match(regex) 
 
    if (match && match.length > 2) { 
 
     var n = match[1].trim(); 
 
     var c = match[2].trim(); 
 
     companiesList.push(n + ' ' + c); 
 
    } 
 
    }); 
 
}); 
 

 
console.log(companiesList)

Проблема заключается в том, что я пропускаю через запятую текста без маркеров после запятой, как: Buzzfeed.

Идея заключается в том, чтобы использовать не захват группу в отрицательном взгляде вперед (см here об инородцах захватывающих групп в матче регулярного выражения)

/([a-zA-Z]*)^(?:(?!ltd).)+$/gi 

Но в этом случае у меня есть любое совпадение, когда во входной струне маркер присутствует:

"Apple, Inc., Microsoft, Inc., Buzzfeed, Treasure LLC".match(/([a-zA-Z]*)^(?:(?!llc).)+$/gi) 

в то время как я хочу, чтобы соответствовать только текст, которые не имеют его, так что я хотел бы получить - как противоположность раньше:

["Buzzfeed"] 

Так как свести на нет/изменить предыдущий код для работы в обоих случаях, чтобы получить в конце наборной массив:

var companiesList = [ 
     "Apple Inc.", 
     "Microsoft Inc.", 
     "Buzzfeed", 
     "Treasure LLC" 
     ]; 
+0

Вы поняли ответ на популярном SO вопрос о соответствии строки, не содержащую ни слова. Вам нужно '(?! Ltd | и т. Д.)' Lookahead, где вы можете добавлять альтернативы после трубы. –

+0

@ WiktorStribiżew uhm это возможно, но проверьте код и попробуйте с тем, что у меня есть некоторые шаблоны для уважения, такие как 'Name, Inc.'. Поэтому мне нужно сопоставить этот шаблон и последний (без). – loretoparisi

+1

Чтобы просто соответствовать Buzzfeed, вам нужно исключить соответствующие «LLC» и т. Д., А также все слова, которые следуют за ними. [Это] (https://jsfiddle.net/wav6gaob/) не выглядит красиво. Возможно, adaneo предлагает лучший выход. –

ответ

1

Не было бы намного проще просто уменьшить его, и просто проверить маркер списка, как вы идете

var tokens = ['Inc.','Ltd','LLC']; 
 
var companies = "Apple, Inc., Microsoft, Inc., Buzzfeed, Treasure, LLC"; 
 

 
var result = companies.split(',').reduce((a,b,i) => { 
 
    return tokens.indexOf(b.trim()) === -1 ? a.push(b.trim()) : a[a.length-1] += b,a; 
 
}, []); 
 

 
console.log(result);

+0

hahaha слишком много «RegExp» над головой в моем сознании. Я предполагаю, что ваше решение в большинстве случаев должно работать очень хорошо! +1. попробует это в моем сценарии, но кажется чрезвычайно умным. – loretoparisi

+1

Это действительно просто предложение, но это было намного проще, чем этот комедийный реггей, и да, он должен работать с чем угодно, если значение находится в токен-листе, и было бы легко сделать его нечувствительным к регистру, обрезать пробел или что-то еще, что вам нужно. – adeneo

+0

Абсолютно спасибо, так как есть нечетные случаи, такие как "Inc." и «inc» и т. д., в какой-то момент, возможно, лучше иметь все, и кошмар регулярного выражения верен! – loretoparisi

1

вы можете использовать регулярное выражение для расщепления.

var companies = "Apple, Inc., Microsoft, Inc., Buzzfeed, Treasure, LLC"; 
 

 
console.log(companies.split(/,\s(?!Inc\.|Ltd|LLC)/i).map(s => s.replace(', ', ' ')));

+0

Это также работает, но как применить к массиву токенов произвольной длины? – loretoparisi

+1

в этом случае уменьшение адено работает лучше. –