Как сопоставить текст с токеном выражением с / без отрицательного взгляда в 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,

Идея состоит в том, чтобы использовать группу без захвата в негативном прогнозе (см. Здесь о группах без захвата в сопоставлении с регулярным выражением)

/([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"
        ];

2 ответа

Решение

Разве не было бы намного проще просто уменьшить его и просто проверять список токенов по ходу дела?

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

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

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

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

Другие вопросы по тегам