Regex для извлечения имени из строки - PullRequest
1 голос
/ 24 мая 2019

Я пытаюсь использовать регулярное выражение для извлечения имени из строки. Имя всегда сопровождается протоколом. Протоколы: ssh, folder, http.

Thu May 23 22:41:55 2019 19 10.10.10.20 22131676 /mnt/tmp/test.txt b s o r John ssh 0 *
Thu May 23 22:42:55 2019 19 10.10.10.20 22131676 /mnt/tmp/test.txt b s o i Jake folder 0 *
Thu May 23 22:41:55 2019 19 10.10.10.20 22131676 /mnt/tmp/test.txt b s o t Steve http 0 *

Ожидаемый результат будет:

John
Jake
Steve

Ответы [ 4 ]

2 голосов
/ 24 мая 2019

Вы можете использовать следующее регулярное выражение PCRE (поскольку вы не уточнили, на каком языке):

\b[a-zA-Z]+(?=\s+(?:ssh|folder|http))

демо: https://regex101.com/r/t62Ra7/4/

Пояснения:

  • \b начать совпадение с границы слова
  • [a-zA-Z]+ сопоставить любую последовательность символов ASCII в диапазоне a-zA-Z, возможно, у вас естьчтобы обобщить это, чтобы принимать буквы Unicode.
  • (?= шаблон предпросмотра, чтобы добавить ограничение, что за именем следует один из протоколов
  • \s+ класс пробельных символов char
  • (?:ssh|folder|http) группа без захвата для протоколов ssh, folder или http
1 голос
/ 24 мая 2019

Попробуйте:

\b[A-Za-z]+(?=\s(?=ssh|folder|http))

Regex Demo здесь .

let regex = /\b[A-Za-z]+(?=\s(?=ssh|folder|http))/g;

[match] = "Thu May 23 22:41:55 2019 19 10.10.10.20 22131676 /mnt/tmp/test.txt b s o r John ssh 0 *".match(regex);
console.log(match); //John

[match] = "Thu May 23 22:42:55 2019 19 10.10.10.20 22131676 /mnt/tmp/test.txt b s o i Jake folder 0 *".match(regex);
console.log(match); //Jake

[match] = "Thu May 23 22:41:55 2019 19 10.10.10.20 22131676 /mnt/tmp/test.txt b s o t Steve http 0 *".match(regex);
console.log(match); //Steve

Объяснение регулярного выражения:

\b определяет границу слова для начала совпадения

[A-Za-z] соответствует любому алфавиту,в любом случае

+ повторять предыдущий символ любое количество раз до следующего шаблона

(?= находит шаблон прогнозирования (который не будет включен в соответствующую группу)

\s пробел

(?=ssh|folder|http) другой взгляд на ssh, folder или http

Собрав все вместе, регулярное выражение ищет слово, котороесопровождается пробелом и затем одним из следующих: ssh, folder или http.

1 голос
/ 24 мая 2019

Вот как вы можете сделать это на Java.

String[] str = {
            "Thu May 23 22:41:55 2019 19 10.10.10.20 22131676 /mnt/tmp/test.txt b s o r John ssh 0 *    ",
            "Thu May 23 22:42:55 2019 19 10.10.10.20 22131676 /mnt/tmp/test.txt b s o i Jake folder 0 * ",
            "Thu May 23 22:41:55 2019 19 10.10.10.20 22131676 /mnt/tmp/test.txt b s o t Steve http 0 *  ",
      };

      String pat = "(\\w+) (ssh|folder|http)"; // need to escape the second \
      Pattern p = Pattern.compile(pat);
      for (String s : str) {
         Matcher m = p.matcher(s);
         if (m.find()) {
            System.out.println(m.group(1));
         }

      }
   }

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

0 голосов
/ 24 мая 2019

Другой подход заключается в том, чтобы взять одну букву и пробел, присутствующие прямо перед именами, в качестве левой границы, затем собрать буквы имен и сохранить их в группе захвата $1, возможно, аналогично:

\s+[a-z]\s+([A-Z][a-z]+)

Мы также можем добавить больше границ, если это может быть необходимо.

enter image description here

RegEx

Если это выражение не требуется, его можно изменить или изменить в regex101.com .

Схема RegEx

jex.im визуализирует регулярные выражения:

enter image description here

ДЕМО

Тест

const regex = /\s+[a-z]\s+([A-Z][a-z]+)/gm;
const str = `Thu May 23 22:41:55 2019 19 10.10.10.20 22131676 /mnt/tmp/test.txt b s o r John ssh 0 *
Thu May 23 22:42:55 2019 19 10.10.10.20 22131676 /mnt/tmp/test.txt b s o i Jake folder 0 *
Thu May 23 22:41:55 2019 19 10.10.10.20 22131676 /mnt/tmp/test.txt b s o t Steve http 0 *`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...