Recherche…


Groupes, nommés et autres.

Ruby étend la syntaxe de groupe standard (...) avec un groupe nommé (?<name>...) . Cela permet l'extraction par nom au lieu d'avoir à compter le nombre de groupes que vous avez.

name_reg = /h(i|ello), my name is (?<name>.*)/i #i means case insensitive

name_input = "Hi, my name is Zaphod Beeblebrox"

match_data = name_reg.match(name_input) #returns either a MatchData object or nil
match_data = name_input.match(name_reg) #works either way

if match_data.nil? #Always check for nil! Common error.
  puts "No match"
else
  match[0] #=> "Hi, my name is Zaphod Beeblebrox"
  match[1] #=> "i" #the first group, (i|ello)
  match[2] #=> "Zaphod Beeblebrox"
  #Because it was a named group, we can get it by name
  match[:name]  #=> "Zaphod Beeblebrox"
  match["name"] #=> "Zaphod Beeblebrox"
  puts "Hello #{match[:name]}!"
end

L'index de la correspondance est compté en fonction de l'ordre des parenthèses de gauche (la totalité de l'expression rationnelle étant le premier groupe à l'index 0)

reg = /(((a)b)c)(d)/
match = reg.match 'abcd'
match[0] #=> "abcd"
match[1] #=> "abc"
match[2] #=> "ab"
match[3] #=> "a"
match[4] #=> "d"

= ~ opérateur

if /hay/ =~ 'haystack'
  puts "There is hay in the word haystack"
end

Note: La commande est importante . Bien que la 'haystack' =~ /hay/ soit dans la plupart des cas équivalente, les effets secondaires peuvent différer:

  • Les chaînes capturées à partir de groupes de capture nommés ne sont affectées à des variables locales que lorsque Regexp#=~ est appelée ( regexp =~ str );
  • Le bon opérande pouvant être un objet arbitraire, pour regexp =~ str il sera appelé soit Regexp#=~ soit String#=~ .

Notez que cela ne renvoie pas une valeur true / false, mais renvoie soit l'index de la correspondance s'il est trouvé, soit nul s'il n'est pas trouvé. Parce que tous les entiers en ruby ​​sont vrais (y compris 0) et nil est faux, cela fonctionne. Si vous voulez une valeur booléenne, utilisez #=== comme indiqué dans un autre exemple .

Quantificateurs

Quantifiers permet de spécifier le nombre de chaînes répétées.

  • Zéro ou un:

    /a?/
    
  • Zéro ou beaucoup:

    /a*/
    
  • Un ou plusieurs:

    /a+/
    
  • Nombre exact:

    /a{2,4}/ # Two, three or four
    /a{2,}/  # Two or more
    /a{,4}/  # Less than four (including zero)
    

Par défaut, les quantificateurs sont gourmands , ce qui signifie qu’ils prennent autant de caractères qu’ils le peuvent tout en effectuant une correspondance. Normalement, cela ne se remarque pas:

/(?<site>.*) Stack Exchange/ =~ 'Motor Vehicle Maintenance & Repair Stack Exchange'

Le site groupe de capture nommé sera défini sur "Maintenance et réparation des véhicules automobiles" comme prévu. Mais si «Stack Exchange» est une partie facultative de la chaîne (car il pourrait s'agir de «Stack Overflow» à la place), la solution naïve ne fonctionnera pas comme prévu:

/(?<site>.*)( Stack Exchange)?/

Cette version correspondra toujours, mais la capture nommée inclura "Stack Exchange" puisque * mange avidement ces caractères. La solution consiste à ajouter un autre point d'interrogation pour rendre le * paresseux:

/(?<site>.*?)( Stack Exchange)?/

Ajout ? à tout quantificateur le rendra paresseux.

Classes de caractères

Décrit les plages de symboles

Vous pouvez énumérer explicitement les symboles

/[abc]/ # 'a' or 'b' or 'c'

Ou utiliser des gammes

/[a-z]/ # from 'a' to 'z'

Il est possible de combiner des plages et des symboles simples

/[a-cz]/ # 'a' or 'b' or 'c' or 'z'

Le trait d'union ( - ) est traité comme charachter

/[-a-c]/ # '-' or 'a' or 'b' or 'c'

Les classes peuvent être négatives lorsque des symboles précèdent avec ^

/[^a-c]/ # Not 'a', 'b' or 'c'

Il existe des raccourcis pour les classes répandues et les charachters spéciaux, ainsi que des fins de ligne

^  # Start of line
$  # End of line
\A # Start of string
\Z # End of string, excluding any new line at the end of string
\z # End of string
.  # Any single character
\s # Any whitespace character
\S # Any non-whitespace character
\d # Any digit
\D # Any non-digit
\w # Any word character (letter, number, underscore)
\W # Any non-word character
\b # Any word boundary

\n se comprendra simplement comme nouvelle ligne

Pour échapper à n'importe quel charachter réservé, tel que / ou [] et d'autres, utilisez une barre oblique inverse (barre oblique à gauche)

\\ # => \
\[\] # => []

Expressions régulières dans les déclarations de cas

Vous pouvez tester si une chaîne correspond à plusieurs expressions régulières à l'aide d'une instruction switch.

Exemple

case "Ruby is #1!"
when /\APython/
    puts "Boooo."
when /\ARuby/
    puts "You are right."
else 
    puts "Sorry, I didn't understand that."
end

Cela fonctionne parce que les instructions de cas sont vérifiées pour l'égalité en utilisant l'opérateur === , pas l'opérateur == . Quand une regex est sur le côté gauche d'une comparaison utilisant === , elle testera une chaîne pour voir si elle correspond.

Définir une expression rationnelle

Une expression régulière peut être créée de trois manières différentes dans Ruby.

  • en utilisant des barres obliques: / /

  • en utilisant %r{}

  • en utilisant Regex.new

    #The following forms are equivalent
    regexp_slash = /hello/
    regexp_bracket = %r{hello}
    regexp_new = Regexp.new('hello')
    
    string_to_match = "hello world!"
    
    #All of these will return a truthy value
    string_to_match =~ regexp_slash    # => 0
    string_to_match =~ regexp_bracket  # => 0
    string_to_match =~ regexp_new      # => 0
    

rencontre? - Résultat booléen

Retourne true ou false , qui indique si l'expression rationnelle est mise en correspondance ou non sans mettre $~ jour $~ et d'autres variables associées. Si le second paramètre est présent, il spécifie la position dans la chaîne pour commencer la recherche.

/R.../.match?("Ruby")    #=> true
/R.../.match?("Ruby", 1) #=> false
/P.../.match?("Ruby")    #=> false

Ruby 2.4+

Utilisation rapide commune

Les expressions régulières sont souvent utilisées dans les méthodes en tant que paramètres pour vérifier si d'autres chaînes sont présentes ou pour rechercher et / ou remplacer des chaînes.

Vous verrez souvent ce qui suit:

string = "My not so long string"
string[/so/] # gives so
string[/present/] # gives nil
string[/present/].nil? # gives true

Donc, vous pouvez simplement l'utiliser comme une vérification si une chaîne contient une sous-chaîne

puts "found" if string[/so/]

Plus avancé mais toujours court et rapide: recherchez un groupe spécifique en utilisant le deuxième paramètre, 2 est le second dans cet exemple car la numérotation commence à 1 et non à 0, un groupe est ce qui est entre parenthèses.

string[/(n.t).+(l.ng)/, 2] # gives long

Aussi souvent utilisé: rechercher et remplacer par sub ou gsub , \1 donne le premier groupe trouvé, \2 le second:

string.gsub(/(n.t).+(l.ng)/, '\1 very \2') # My not very long string

Le dernier résultat est mémorisé et peut être utilisé sur les lignes suivantes

$2 # gives long


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow