1
votes

Regex pour extraire le nom d'une chaîne

J'essaie d'utiliser une expression régulière pour extraire le nom d'une chaîne. Le nom suit toujours un protocole. Les protocoles sont: ssh , dossier , http.

John
Jake
Steve

La sortie attendue serait: p>

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 *


0 commentaires

4 Réponses :


1
votes

Voici comment vous pouvez le faire en 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));
         }

      }
   }

Le modèle réel est dans la chaîne pat et peut être utilisé avec d'autres moteurs d'expression régulière. Cela correspond simplement à un nom suivi d'un espace suivi des protocoles ou ensemble. Mais il capture le nom dans le premier groupe de capture.


0 commentaires

1
votes

Essayez :

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

Démo Regex ici .

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

Explication Regex:

\ b définit une limite de mot pour commencer la correspondance

[A-Za-z] correspond à n'importe quel alphabet, dans tous les cas

+ répéter le caractère précédent autant de fois que nécessaire jusqu'au modèle suivant

(? = trouve le modèle de recherche anticipée (qui ne sera pas inclus dans le groupe correspondant)

\ s un espace

(? = ssh | dossier | http) une autre recherche vers ssh , dossier ou http

En mettant tout cela ensemble, l'expression régulière recherche un mot suivi d'un espace, puis de l'un des éléments suivants: ssh, dossier ou http.


6 commentaires

2 points ici: vous n'avez pas besoin d'avoir une anticipation imbriquée, et le point le plus important est que [A-z] ne se comporte pas comme vous le pensez !!!!! cela ne correspondra pas uniquement aux lettres !!!! stackoverflow.com/ questions / 4923380 /…


votre regex accepte J] ohn , Ja [ke , ... >>> regex101.com/r/T4gayx/1


Bonne prise, très appréciée! Corrigé maintenant.


[A-ZA-z] correspondra toujours plus que ce que vous voulez regex101 .com / r / T4gayx / 2 , la plage correcte est [A-Za-z]


Correction de la faute de frappe dans le texte. L'extrait de code et le code de démonstration étaient bien cependant. Encore une fois, merci pour la capture!


Visuellement >>> cs.cmu.edu/~ pattis / 15-1XX / common / handouts / ascii.html [Az] acceptera les caractères pour lesquels la valeur déc ascii est comprise entre 65 et 122 , y compris [\ ^ _ qui ne sont pas des lettres.



2
votes

Vous pouvez utiliser l'expression régulière PCRE suivante (car vous n'avez pas précisé la langue):

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

démo: https://regex101.com/r/t62Ra7/4/

Explications: fort>

  • \ b démarrer la correspondance à partir d'une limite de mot
  • [a-zA-Z] + correspond à n'importe quelle séquence de caractères ASCII dans la plage a-zA-Z, vous devrez peut-être généraliser cela pour accepter les lettres Unicode.
  • (? = modèle lookahead pour ajouter la contrainte que le nom soit suivi par l'un des protocoles
  • \ s + un caractère de classe d'espaces
  • (?: ssh | dossier | http) groupe non capturant pour les protocoles ssh , dossier ou http code>


0 commentaires

0
votes

Une autre approche consisterait à prendre la lettre unique et l'espace présents juste avant les noms comme limite gauche, puis à collecter les lettres des noms et à les enregistrer dans le groupe de capture $ 1 , peut-être similaire à:

pre> XXX

Nous pouvons également y ajouter d'autres limites, si cela s'avère nécessaire.

 entrez la description de l'image ici

RegEx

Si cette expression n'était pas souhaitée, elle peut être modifiée ou changée dans regex101.com .

Circuit RegEx

jex.im visualise les expressions régulières:

 entrez la description de l'image ici

DEMO

Test

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


0 commentaires