Regex multiple @mentions с Javascript [дубликат]

public class MenuFragment extends Fragment implements View.OnClickListener {
    private Context mContext;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        FragmentMenuBinding binding=FragmentMenuBinding.inflate(inflater,container,false);
        View view=binding.getRoot();
        mContext=view.getContext();
        return view;
    }
}
91
задан gatlin 12 June 2011 в 18:27
поделиться

13 ответов

Продолжить вызов re.exec(s) в цикле для получения всех совпадений:

var re = /\s*([^[:]+):\"([^"]+)"/g;
var s = '[description:"aoeu" uuid:"123sth"]';
var m;

do {
    m = re.exec(s);
    if (m) {
        console.log(m[1], m[2]);
    }
} while (m);

Попробуйте это с помощью jsfiddle: http://jsfiddle.net/7yS2V/

119
ответ дан lawnsea 20 August 2018 в 10:26
поделиться
  • 1
    Почему не while вместо do … while? – Gumbo 12 June 2011 в 19:14
  • 2
    Использование цикла while делает его немного неудобным для инициализации m. Вам также нужно написать while(m = re.exec(s)), который является анти-шаблонным IMO, или вам нужно написать m = re.exec(s); while (m) { ... m = re.exec(s); }. Я предпочитаю do ... if ... while идиому, но другие методы тоже будут работать. – lawnsea 12 June 2011 в 19:21
  • 3
    делая это в хромированном состоянии, я привел к сбою моей вкладки. – EdgeCaseBerg 16 December 2014 в 19:53
  • 4
    @EdgeCaseBerg У вас должен быть установлен флаг g, иначе внутренний указатель не будет перемещен вперед. Docs . – Tim 25 July 2015 в 13:45
  • 5
    Другое дело, что если регулярное выражение может соответствовать пустой строке, это будет бесконечный цикл – FabioCosta 8 June 2017 в 00:57

Вот моя функция для получения совпадений:

function getAllMatches(regex, text) {
    if (regex.constructor !== RegExp) {
        throw new Error('not RegExp');
    }

    var res = [];
    var match = null;

    if (regex.global) {
        while (match = regex.exec(text)) {
            res.push(match);
        }
    }
    else {
        if (match = regex.exec(text)) {
            res.push(match);
        }
    }

    return res;
}

var regex = /abc|def|ghi/g;
var res = getAllMatches(regex, 'abcdefghi');

res.forEach(function (item) {
    console.log(item[0]);
});
3
ответ дан Agus Syahputra 20 August 2018 в 10:26
поделиться

str.match(pattern) вернет все совпадения в виде массива. Я думаю, что это самый простой способ.

Например -

"All of us except @Emran, @Raju and @Noman was there".match(/@\w*/g)
// Will return ["@Emran", "@Raju", "@Noman"]
60
ответ дан Anis 20 August 2018 в 10:26
поделиться
  • 1
    Остерегайтесь: совпадения не соответствуют объектам, а соответствуют строкам. Например, нет доступа к группам в "All of us except @Emran:emran26, @Raju:raju13 and @Noman:noman42".match(/@(\w+):(\w+)/g) (который вернет ["@Emran:emran26", "@Raju:raju13", "@Noman:noman42"]) – madprog 18 August 2017 в 09:46
  • 2
    @madprog. Правильно, это самый простой способ, но не подходит, когда значения группы необходимы. – Anis 13 September 2017 в 10:02

На основе функции Agus, но я предпочитаю возвращать только значения соответствия:

var bob = "> bob <";
function matchAll(str, regex) {
    var res = [];
    var m;
    if (regex.global) {
        while (m = regex.exec(str)) {
            res.push(m[1]);
        }
    } else {
        if (m = regex.exec(str)) {
            res.push(m[1]);
        }
    }
    return res;
}
var Amatch = matchAll(bob, /(&.*?;)/g);
console.log(Amatch);  // yeilds: [>, <]
4
ответ дан bob 20 August 2018 в 10:26
поделиться

Вот мой ответ:

var str = '[me nombre es] : My name is. [Yo puedo] is the right word'; 

var reg = /\[(.*?)\]/g;

var a = str.match(reg);

a = a.toString().replace(/[\[\]]/g, "").split(','));
-3
ответ дан daguang 20 August 2018 в 10:26
поделиться
  • 1
    Ваша строка ввода (str) имеет неправильный формат (слишком много жестких скобок). Вы захватываете только ключ, а не значение. Ваш код имеет синтаксическую ошибку и не выполняет (последние скобки). Если вы ответите «old & quot; вопрос с уже воспринятым ответом, убедитесь, что вы добавили больше знаний и лучшего ответа, а затем уже принятого. Я не думаю, что ваш ответ делает это. – Cleared 3 July 2017 в 06:34

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

Я упростил регулярное выражение в ответе, чтобы быть более ясным (это не решение вашей точной проблемы).

var re = /^(.+?):"(.+)"$/
var regExResult = re.exec('description:"aoeu"');
var purifiedResult = purify_regex(regExResult);

// We only want the group matches in the array
function purify_regex(reResult){

  // Removes the Regex specific values and clones the array to prevent mutation
  let purifiedArray = [...reResult];

  // Removes the full match value at position 0
  purifiedArray.shift();

  // Returns a pure array without mutating the original regex result
  return purifiedArray;
}

// purifiedResult= ["description", "aoeu"]

Это выглядит более подробным, чем из-за комментариев, это то, что он выглядит как без комментариев

var re = /^(.+?):"(.+)"$/
var regExResult = re.exec('description:"aoeu"');
var purifiedResult = purify_regex(regExResult);

function purify_regex(reResult){
  let purifiedArray = [...reResult];
  purifiedArray.shift();
  return purifiedArray;
}

Обратите внимание, что любые группы, которые не соответствуют, будут перечислены в массиве как значения undefined.

В этом решении используется оператор распространения ES6 для очистки массив специальных значений регулярных выражений. Вам нужно будет запустить ваш код через Babel , если вы хотите поддержку IE11.

0
ответ дан Daniel Tonon 20 August 2018 в 10:26
поделиться

Это решение

var s = '[description:"aoeu" uuid:"123sth"]';

var re = /\s*([^[:]+):\"([^"]+)"/g;
var m;
while (m = re.exec(s)) {
  console.log(m[1], m[2]);
}

Это основано на ответе lawnsea, но короче.

Обратите внимание, что флаг `g 'должен быть установлен для перемещения внутреннего указателя вперед через вызовы.

44
ответ дан Jay Taylor 20 August 2018 в 10:26
поделиться

Для меня важна функция findall, поэтому я упаковал ответ lawnsea в функцию для простой копирования и вставки.

function findall(regex_pattern, string_)
    {
        var output_list = [];
        while (true) 
            {
                var a_match = regex_pattern.exec(string_);
                if (a_match) 
                    {
                        // get rid of the string copy
                        delete a_match.input;
                        // store the match data
                        output_list.push(a_match);
                    }
                else
                    {
                        break;
                    }
            } 
        return output_list;
    }

пример использования:

console.log(   findall(/blah/g,'blah1 blah2')   ) 

выходов :

[ [ 'blah', index: 0 ], [ 'blah', index: 6 ] ]
1
ответ дан Jeff Hykin 20 August 2018 в 10:26
поделиться

OMG Я не понимаю, что с 2011 года никто не отправил хороший ответ.

Предположим, что ваша строка похожа на [key: "val" key2: "val2"], как указано выше @gatlin , и вы хотите получить все совпадения с использованием регулярного выражения: вы можете наслаждаться вторым параметром функции replace, который может быть функцией обратного вызова ... и затем получить все аргументы, найденные вашим регулярным выражением. Ниже приведен пример, который вы можете играть в консоли:

var str = '[foo:"bar" thud:"grunt" bazola:"ztesch"]';
var regex = new RegExp('(\\w+):"(\\w+)"', 'ig');
var table = [];
str.replace(regex, function() {
    var matches = arguments;
    table.push(matches);
});
console.log(table);
//=> ["foo:"bar"", "foo", "bar", 1, .....
0
ответ дан marcdahan 20 August 2018 в 10:26
поделиться

Чтобы перебрать все совпадения, вы можете использовать функцию replace:

var re = /\s*([^[:]+):\"([^"]+)"/g;
var s = '[description:"aoeu" uuid:"123sth"]';

s.replace(re, function(match, g1, g2) { console.log(g1, g2); });
68
ответ дан mik01aj 20 August 2018 в 10:26
поделиться
  • 1
    Я буду рад услышать объяснение для downvotes и удалить запрос. – Christophe 12 May 2016 в 17:05
  • 2
    Я удивлен, что этот ответ получил вниз. Это самый простой. В самом деле. Сравните это с любым другим. – mik01aj 15 June 2016 в 11:12
  • 3
    Согласовано; это было именно то, что я искал, спасибо! – Levi 16 August 2016 в 23:05
  • 4
    Я согласен определенно простейший и самый легкий для понимания. – Justin 10 March 2017 в 15:49
  • 5
    Это противоречивый код. Вы не «заменяете» что-либо в каком-либо значимом смысле. Это просто использование некоторой функции для другой цели. – Luke Maurer 27 July 2017 в 19:43

Итераторы более приятны:

const matches = (text, pattern) => ({
  [Symbol.iterator]: function * () {
    const clone = new RegExp(pattern.source, pattern.flags);
    let match = null;
    do {
      match = clone.exec(text);
      if (match) {
        yield match;
      }
    } while (match);
  }
});

Использование в цикле:

for (const match of matches('abcdefabcdef', /ab/g)) {
  console.log(match);
}

Или если вы хотите массив:

[ ...matches('abcdefabcdef', /ab/g) ]
1
ответ дан sdgfsdh 20 August 2018 в 10:26
поделиться

Я бы определенно рекомендовал использовать функцию String.match () и создать для него соответствующий RegEx. Мой пример - со списком строк, который часто необходим при сканировании входов пользователя для ключевых слов и фраз.

    // 1) Define keywords
    var keywords = ['apple', 'orange', 'banana'];

    // 2) Create regex, pass "i" for case-insensitive and "g" for global search
    regex = new RegExp("(" + keywords.join('|') + ")", "ig");
    => /(apple|orange|banana)/gi

    // 3) Match it against any string to get all matches 
    "Test string for ORANGE's or apples were mentioned".match(regex);
    => ["ORANGE", "apple"]

Надеюсь, это поможет!

0
ответ дан Sebastian Scholl 20 August 2018 в 10:26
поделиться

Используйте это ...

var all_matches = your_string.match(re);
console.log(all_matches)

Он вернет массив всех совпадений ... Это будет работать нормально ... Но помните, что он не будет принимать группы в учетной записи. Он просто вернет полные совпадения ...

0
ответ дан Subham Debnath 20 August 2018 в 10:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: