Un outil de type grep
qui comprend la syntaxe du code source et permet des manipulations en plus de la recherche.
Comme grep
, les expressions régulières sont une primitive essentielle. Contrairement à grep
, des fonctionnalités supplémentaires permettent une plus grande précision , avec des options de manipulation . Cela permet srgn
d'opérer selon des dimensions, les expressions régulières et les outils IDE ( Renommer tout , Rechercher toutes les références , ...) ne peuvent pas à eux seuls les compléter.
srgn
est organisé autour d'actions à entreprendre (le cas échéant), agissant uniquement dans des domaines précis, éventuellement sensibles à la grammaire du langage . En termes d'outils existants, considérez-le comme un mélange de tr
, sed
, ripgrep et tree-sitter
, avec un objectif de conception simple : si vous connaissez les regex et les bases du langage avec lequel vous travaillez, vous êtes prêt à partir. .
Conseil
Tous les extraits de code affichés ici sont vérifiés dans le cadre de tests unitaires utilisant le binaire srgn
réel. Ce qui est présenté ici est garanti de fonctionner.
L'utilisation srgn
la plus simple fonctionne de manière similaire à tr
:
$ echo ' Hello World! ' | srgn ' [wW]orld ' ' there ' # replacement
Hello there !
Les correspondances pour le modèle d'expression régulière '[wW]orld'
(le scope ) sont remplacées (l' action ) par le deuxième argument de position. Zéro ou plusieurs actions peuvent être spécifiées :
$ echo ' Hello World! ' | srgn ' [wW]orld ' # zero actions: input returned unchanged
Hello World !
$ echo ' Hello World! ' | srgn --upper ' [wW]orld ' ' you ' # two actions: replacement, afterwards uppercasing
Hello YOU !
Le remplacement est toujours effectué en premier et spécifié en termes de position. Toutes les autres actions sont appliquées après et données sous forme d'indicateurs de ligne de commande.
De même, plusieurs portées peuvent être spécifiées : en plus du modèle regex, une portée sensible à la grammaire du langage peut être donnée, qui s'étend aux éléments syntaxiques du code source (pensez, par exemple, à "tous les corps de définitions class
en Python". ). Si les deux sont donnés, le modèle d’expression régulière n’est alors appliqué que dans cette première portée du langage . Cela permet une recherche et une manipulation avec une précision qui n'est normalement pas possible à l'aide d'expressions régulières simples et sert une dimension différente des outils tels que Rename all dans les IDE.
Par exemple, considérons ce fichier source Python (inutile) :
"""Module for watching birds and their age."""
from dataclasses import dataclass
@ dataclass
class Bird :
"""A bird!"""
name : str
age : int
def celebrate_birthday ( self ):
print ( "?" )
self . age += 1
@ classmethod
def from_egg ( egg ):
"""Create a bird from an egg."""
pass # No bird here yet!
def register_bird ( bird : Bird , db : Db ) -> None :
assert bird . age >= 0
with db . tx () as tx :
tx . insert ( bird )
qui peut être recherché en utilisant:
$ cat birds.py | srgn --python ' class ' ' age '
11: age: int
15: self.age += 1
L' age
de la chaîne a été recherché et trouvé uniquement dans les définitions class
Python (et non, par exemple, dans des corps de fonction tels que register_bird
, où age
apparaît également et serait presque impossible à exclure de la prise en compte dans vanilla grep
). Par défaut, ce « mode de recherche » imprime également les numéros de ligne. Le mode de recherche est activé si aucune action n'est spécifiée et qu'un langage tel que --python
reçoit 1 — pensez-y comme « ripgrep mais avec des éléments de langage syntaxiques ».
La recherche peut également être effectuée sur plusieurs lignes, par exemple pour trouver des méthodes (alias def
inside class
) manquant de docstrings :
$ cat birds.py | srgn --python ' class ' ' def .+:ns+[^"s]{3} ' # do not try this pattern at home
13: def celebrate_birthday(self):
14: print("?")
Notez que cela ne fait surface ni from_egg
(a une docstring) ni register_bird
(pas une méthode, def
en dehors class
).
Les étendues de langue elles-mêmes peuvent également être spécifiées plusieurs fois. Par exemple, dans l'extrait Rust
pub enum Genre {
Rock ( Subgenre ) ,
Jazz ,
}
const MOST_POPULAR_SUBGENRE : Subgenre = Subgenre :: Something ;
pub struct Musician {
name : String ,
genres : Vec < Subgenre > ,
}
plusieurs éléments peuvent être percés chirurgicalement comme
$ cat music.rs | srgn --rust ' pub-enum ' --rust ' type-identifier ' ' Subgenre ' # AND'ed together
2: Rock(Subgenre),
où seules les lignes correspondant à tous les critères sont renvoyées, agissant comme une logique et entre toutes les conditions. Notez que les conditions sont évaluées de gauche à droite, ce qui empêche certaines combinaisons d'avoir un sens : par exemple, la recherche d'un corps class
Python à l'intérieur de doc-strings
Python ne renvoie généralement rien. L'inverse fonctionne cependant comme prévu :
$ cat birds.py | srgn --py ' class ' --py ' doc-strings '
8: """A bird!"""
19: """Create a bird from an egg."""
Aucune docstring en dehors des corps class
n'est visible !
L'indicateur -j
modifie ce comportement : de l'intersection de gauche à droite, à l'exécution de toutes les requêtes indépendamment et à la jointure de leurs résultats, vous permettant ainsi de rechercher plusieurs manières à la fois :
$ cat birds.py | srgn -j --python ' comments ' --python ' doc-strings ' ' bird[^s] '
8: """A bird!"""
19: """Create a bird from an egg."""
20: pass # No bird here yet!
Le modèle bird[^s]
a également été trouvé à l'intérieur des commentaires ou des docstrings, pas seulement des "docstrings dans les commentaires".
Si l'entrée standard n'est pas fournie, srgn
sait comment trouver automatiquement les fichiers sources pertinents, par exemple dans ce référentiel :
$ srgn --python ' class ' ' age '
docs/samples/birds
11: age: int
15: self.age += 1
docs/samples/birds.py
9: age: int
13: self.age += 1
Il parcourt de manière récursive son répertoire actuel, trouvant des fichiers basés sur des extensions de fichiers et des lignes shebang, et les traitant à très grande vitesse. Par exemple, srgn --go strings 'd+'
recherche et imprime les ~140 000 séries de chiffres dans les chaînes Go littérales à l'intérieur de la base de code Kubernetes d'environ 3 000 000 de lignes de code Go en 3 secondes sur 12 cœurs de M3. Pour en savoir plus sur l'utilisation de nombreux fichiers, voir ci-dessous.
Les portées et les actions peuvent être combinées presque arbitrairement (même si de nombreuses combinaisons ne seront pas utiles, ni même significatives). Par exemple, considérons cet extrait de code Python (pour des exemples utilisant d'autres langages pris en charge, voir ci-dessous) :
"""GNU module."""
def GNU_says_moo ():
"""The GNU function -> say moo -> ✅"""
GNU = """
GNU
""" # the GNU...
print ( GNU + " says moo" ) # ...says moo
sur lequel la commande suivante est exécutée :
cat gnu.py | srgn --titlecase --python ' doc-strings ' ' (?' ' $1: GNU ? is not Unix '
L'anatomie de cette invocation est la suivante :
--titlecase
(une action) Titlecase tout ce qui est trouvé dans la portée
--python 'doc-strings'
(une portée) s'étendra (c'est-à-dire ne prendra en considération que) les docstrings selon la grammaire du langage Python
'(? (une portée) ne voit que ce qui était déjà couvert par l'option précédente et le réduira davantage. Il ne pourra jamais étendre la portée précédente. La portée de l’expression régulière est appliquée après toute portée de langage.
(? est une syntaxe d'analyse négative, démontrant comment cette fonctionnalité avancée est disponible. Les chaînes de
GNU
préfixées par The
ne seront pas prises en compte.
'$1: GNU ? is not Unix'
(une action) remplacera chaque occurrence correspondante (c'est-à-dire chaque section d'entrée trouvée comme étant dans la portée) par cette chaîne. Les occurrences correspondantes sont des modèles de '(? uniquement dans les docstrings Python. Notamment, cette chaîne de remplacement démontre :
$1
, qui transporte le contenu capturé par le premier groupe d'expressions régulières de capture. C'est ([az]+)
, car (? ne capture pas.
La commande utilise plusieurs portées (langage et modèle d'expression régulière) et plusieurs actions (remplacement et casse du titre). Le résultat s'écrit alors
"""Module: GNU ? Is Not Unix."""
def GNU_says_moo ():
"""The GNU function -> say moo -> ✅"""
GNU = """
GNU
""" # the GNU...
print ( GNU + " says moo" ) # ...says moo
où les changements se limitent à :
- """GNU module."""
+ """Module: GNU ? Is Not Unix."""
def GNU_says_moo():
"""The GNU -> say moo -> ✅"""
Avertissement
Pendant que srgn
est en version bêta (version majeure 0), assurez-vous de traiter uniquement (de manière récursive) les fichiers que vous pouvez restaurer en toute sécurité.
Le mode de recherche n’écrase pas les fichiers et est donc toujours sécurisé.
Voir ci-dessous pour la sortie d'aide complète de l'outil.
Note
Les langues prises en charge sont
Téléchargez un binaire prédéfini à partir des versions.
Cette caisse fournit ses binaires dans un format compatible avec cargo-binstall
:
cargo install cargo-binstall
(cela peut prendre un certain temps)cargo binstall srgn
(quelques secondes, pendant qu'il télécharge les binaires prédéfinis depuis GitHub)Ces étapes sont garanties de fonctionner™, car elles sont testées en CI. Ils fonctionnent également si aucun binaire prédéfini n'est disponible pour votre plate-forme, car l'outil reviendra à la compilation à partir des sources.
Une formule est disponible via :
brew install srgn
Disponible via instable :
nix-shell -p srgn
Disponible via l'AUR.
Un port est disponible :
sudo port install srgn
Toutes les images du coureur GitHub Actions sont livrées avec cargo
préinstallé, et cargo-binstall
fournit une action GitHub pratique :
jobs :
srgn :
name : Install srgn in CI
# All three major OSes work
runs-on : ubuntu-latest
steps :
- uses : cargo-bins/cargo-binstall@main
- name : Install binary
run : >
cargo binstall
--no-confirm
srgn
- name : Use binary
run : srgn --version
Ce qui précède se termine en seulement 5 secondes au total, car aucune compilation n'est requise. Pour plus de contexte, consultez les conseils de cargo-binstall
sur CI.
Sous Linux, gcc
fonctionne.
Sur macOS, utilisez clang
.
Sous Windows, MSVC fonctionne.
Sélectionnez "Développement bureautique avec C++" lors de l'installation.
cargo install srgn
cargo add srgn
Voir ici pour en savoir plus.
Différents shells sont pris en charge pour les scripts de complétion de shell. Par exemple, ajoutez eval "$(srgn --completions zsh)"
à ~/.zshrc
pour les complétions dans ZSH. Une session interactive peut alors ressembler à :
L'outil est conçu autour de périmètres et d'actions . Les étendues réduisent les parties de l’entrée à traiter. Les actions effectuent ensuite le traitement. Généralement, les portées et les actions sont composables, donc plusieurs de chaque peuvent être transmises. Les deux sont facultatifs (mais ne rien faire est inutile) ; ne spécifier aucune portée implique que l’intégralité de l’entrée est dans la portée.
Dans le même temps, il existe un chevauchement considérable avec plain tr
: l'outil est conçu pour avoir une correspondance étroite dans les cas d'utilisation les plus courants, et n'aller au-delà que lorsque cela est nécessaire.
L'action la plus simple est le remplacement. Il est spécialement accessible (en tant qu'argument et non en option) pour la compatibilité avec tr
et l'ergonomie générale. Toutes les autres actions sont données sous forme d'indicateurs ou d'options si elles prennent une valeur.
Par exemple, les remplacements simples d'un seul caractère fonctionnent comme dans tr
:
$ echo ' Hello, World! ' | srgn ' H ' ' J '
Jello, World!
Le premier argument est la portée (littérale H
dans ce cas). Tout ce qui correspond est soumis à un traitement (remplacement par J
, le deuxième argument, dans ce cas). Cependant, il n'y a pas de concept direct de classes de caractères comme dans tr
. Au lieu de cela, par défaut, la portée est un modèle d'expression régulière, ses classes peuvent donc être utilisées avec un effet similaire :
$ echo ' Hello, World! ' | srgn ' [a-z] ' ' _ '
H____, W____!
Le remplacement se produit avidement tout au long de la correspondance par défaut (notez la classe de caractères UTS, qui rappelle tr
's [:alnum:]
) :
$ echo ' ghp_oHn0As3cr3T!! ' | srgn ' ghp_[[:alnum:]]+ ' ' * ' # A GitHub token
*!!
Les fonctionnalités avancées d'expression régulière sont prises en charge, par exemple les recherches :
$ echo ' ghp_oHn0As3cr3T ' | srgn ' (?<=ghp_)[[:alnum:]]+ ' ' * '
ghp_*
Faites attention à les utiliser en toute sécurité, car les modèles avancés sont livrés sans certaines garanties de sécurité et de performances. S'ils ne sont pas utilisés, les performances ne sont pas affectées.
Le remplacement n'est pas limité à un seul caractère. Il peut s'agir de n'importe quelle chaîne, par exemple pour corriger cette citation :
$ echo ' "Using regex, I now have no issues." ' | srgn ' no issues ' ' 2 problems '
"Using regex, I now have 2 problems."
L'outil est entièrement compatible Unicode, avec une prise en charge utile pour certaines classes de caractères avancées :
$ echo ' Mood: ? ' | srgn ' ? ' ' ? '
Mood: ?
$ echo ' Mood: ???? :( ' | srgn ' p{Emoji_Presentation} ' ' ? '
Mood: ???? :(
Les remplaçants connaissent les variables, qui sont rendues accessibles pour une utilisation via des groupes de capture d'expressions régulières. Les groupes de capture peuvent être numérotés ou éventuellement nommés. Le groupe de capture zéro correspond à l'ensemble du match.
$ echo ' Swap It ' | srgn ' (w+) (w+) ' ' $2 $1 ' # Regular, numbered
It Swap
$ echo ' Swap It ' | srgn ' (w+) (w+) ' ' $2 $1$1$1 ' # Use as many times as you'd like
It SwapSwapSwap
$ echo ' Call +1-206-555-0100! ' | srgn ' Call (+?d-d{3}-d{3}-d{4}).+ ' ' The phone number in "$0" is: $1. ' # Variable `0` is the entire match
The phone number in "Call +1-206-555-0100!" is: +1-206-555-0100.
Un cas d'utilisation plus avancé est, par exemple, la refactorisation de code à l'aide de groupes de capture nommés (vous pouvez peut-être en proposer un plus utile...) :
$ echo ' let x = 3; ' | srgn ' let (?[a-z]+) = (?.+); ' ' const $var$var = $expr + $expr; '
const xx = 3 + 3;
Comme dans bash, utilisez des accolades pour lever l'ambiguïté des variables du contenu immédiatement adjacent :
$ echo ' 12 ' | srgn ' (d)(d) ' ' $2${1}1 '
211
$ echo ' 12 ' | srgn ' (d)(d) ' ' $2$11 ' # will fail (`11` is unknown)
$ echo ' 12 ' | srgn ' (d)(d) ' ' $2${11 ' # will fail (brace was not closed)
Étant donné que le remplacement n’est qu’une chaîne statique, son utilité est limitée. C'est là que la sauce secrète de tr
entre habituellement en jeu : utiliser ses classes de caractères, qui sont également valables en deuxième position, traduisant parfaitement les membres de la première vers la seconde. Ici, ces classes sont plutôt des expressions rationnelles, et valables uniquement en première position (la portée). Une expression régulière étant une machine à états, il est impossible de la faire correspondre à une « liste de caractères », qui dans tr
est le deuxième argument (facultatif). Ce concept a disparu et sa flexibilité a été perdue.
Au lieu de cela, les actions proposées, toutes fixes , sont utilisées. Un coup d'œil aux cas d'utilisation les plus courants de tr
révèle que l'ensemble d'actions fourni les couvre pratiquement tous ! N'hésitez pas à signaler un problème si votre cas d'utilisation n'est pas couvert.
Passons à la prochaine action.
Supprime tout ce qui est trouvé de l'entrée. Même nom de drapeau que dans tr
.
$ echo ' Hello, World! ' | srgn -d ' (H|W|!) '
ello, orld
Note
Comme la portée par défaut doit correspondre à l'intégralité de l'entrée, c'est une erreur de spécifier une suppression sans portée.
Récupère les répétitions de caractères correspondant à la portée en occurrences uniques. Même nom de drapeau que dans tr
.
$ echo ' Helloooo Woooorld!!! ' | srgn -s ' (o|!) '
Hello World!
Si une classe de caractères est transmise, tous les membres de cette classe sont regroupés dans le membre de classe rencontré en premier :
$ echo ' The number is: 3490834 ' | srgn -s ' d '
The number is: 3
La gourmandise en matching n’est pas modifiée, alors attention :
$ echo ' Winter is coming... ??? ' | srgn -s ' ?+ '
Winter is coming... ???
Note
Le motif correspond à toute la série de soleils, il n'y a donc rien à presser. L'été l'emporte.
Inversez la gourmandise si le cas d’utilisation l’exige :
$ echo ' Winter is coming... ??? ' | srgn -s ' ?+? ' ' ☃️ '
Winter is coming... ☃️
Note
Encore une fois, comme pour la suppression, spécifier une compression sans portée explicite est une erreur. Sinon, toute l’entrée est compressée.
Une bonne partie de l'utilisation tr
entre dans cette catégorie. C'est très simple.
$ echo ' Hello, World! ' | srgn --lower
hello, world!
$ echo ' Hello, World! ' | srgn --upper
HELLO, WORLD!
$ echo ' hello, world! ' | srgn --titlecase
Hello, World!
Décompose l'entrée selon le formulaire de normalisation D, puis supprime les points de code de la catégorie Mark (voir exemples). Cela signifie en gros : prenez un personnage fantaisiste, arrachez des morceaux qui pendent, jetez-les.
$ echo ' Naïve jalapeño ärgert mgła ' | srgn -d ' P{ASCII} ' # Naive approach
Nave jalapeo rgert mga
$ echo ' Naïve jalapeño ärgert mgła ' | srgn --normalize # Normalize is smarter
Naive jalapeno argert mgła
Remarquez à quel point mgła
est hors de portée de NFD, car il est « atomique » et donc non décomposable (du moins c'est ce que ChatGPT me murmure à l'oreille).
Cette action remplace les symboles ASCII à plusieurs caractères par des équivalents Unicode natifs à point de code unique appropriés.
$ echo ' (A --> B) != C --- obviously ' | srgn --symbols
(A ⟶ B) ≠ C — obviously
Alternativement, si vous n'êtes intéressé que par les mathématiques, utilisez le cadrage :
$ echo ' A <= B --- More is--obviously--possible ' | srgn --symbols ' <= '
A ≤ B --- More is--obviously--possible
Comme il existe une correspondance 1:1 entre un symbole ASCII et son remplacement, l'effet est réversible 2 :
$ echo ' A ⇒ B ' | srgn --symbols --invert
A => B
Il n’existe actuellement qu’un ensemble limité de symboles pris en charge, mais d’autres peuvent être ajoutés.
Cette action remplace les orthographes alternatives des caractères spéciaux allemands (ae, oe, ue, ss) par leurs versions natives (ä, ö, ü, ß) 3 .
$ echo ' Gruess Gott, Neueroeffnungen, Poeten und Abenteuergruetze! ' | srgn --german
Grüß Gott, Neueröffnungen, Poeten und Abenteuergrütze!
Cette action est basée sur une liste de mots (compilez sans fonctionnalité german
si cela gonfle trop votre binaire). Notez les caractéristiques suivantes concernant l'exemple ci-dessus :
Poeten
est resté tel quel, au lieu d'être converti naïvement et par erreur en Pöten
Abenteuergrütze
ne figurera dans aucune liste de mots raisonnable, mais a néanmoins été traité correctementAbenteuer
est également resté tel quel, au lieu d'être incorrectement converti en Abenteür
Neueroeffnungen
forme sournoisement un élément ue
qu'aucun des mots constitutifs ( neu
, Eröffnungen
) ne possède, mais est toujours traité correctement (malgré les boîtiers incompatibles également)Sur demande, des remplacements peuvent être forcés, comme cela est potentiellement utile pour les noms :
$ echo ' Frau Loetter steht ueber der Mauer. ' | srgn --german-naive ' (?<=Frau )w+ '
Frau Lötter steht ueber der Mauer.
Grâce à une anticipation positive, seule la formule de salutation a été délimitée et donc modifiée. Mauer
est correctement resté tel quel, mais ueber
n'a pas été traité. Un deuxième passage corrige ceci :
$ echo ' Frau Loetter steht ueber der Mauer. ' | srgn --german-naive ' (?<=Frau )w+ ' | srgn --german
Frau Lötter steht über der Mauer.
Note
Les options et les indicateurs relatifs à certains "parents" sont préfixés par le nom de leur parent et impliqueront leur parent lorsqu'ils sont donnés, de sorte que ce dernier n'a pas besoin d'être passé explicitement. C'est pourquoi --german-naive
est nommé tel quel, et --german
n'a pas besoin d'être transmis.
Ce comportement pourrait changer une fois que clap
prendra en charge le chaînage de sous-commandes.
Certaines branches sont indécidables pour ce modeste outil, car il fonctionne sans contexte linguistique. Par exemple, Busse
(bus) et Buße
(pénitence) sont des mots juridiques. Par défaut, les remplacements sont effectués avec gourmandise s'ils sont légaux (c'est tout l'intérêt de srgn
, après tout), mais il existe un indicateur pour activer ce comportement :
$ echo ' Busse und Geluebte ' | srgn --german
Buße und Gelübte
$ echo ' Busse ? und Fussgaenger ?♀️ ' | srgn --german-prefer-original
Busse ? und Fußgänger ?♀️
La plupart des actions sont composables, à moins que cela n'ait aucun sens (comme pour la suppression). Leur ordre d'application est fixe, donc l' ordre des indicateurs donnés n'a aucune influence (le raccordement de plusieurs conduites est une alternative, si nécessaire). Les remplacements ont toujours lieu en premier. Généralement, la CLI est conçue pour éviter les abus et les surprises : elle préfère planter plutôt que faire quelque chose d'inattendu (ce qui est subjectif, bien sûr). Notez que de nombreuses combinaisons sont techniquement possibles, mais peuvent donner des résultats absurdes.
La combinaison d'actions pourrait ressembler à :
$ echo ' Koeffizienten != Bruecken... ' | srgn -Sgu
KOEFFIZIENTEN ≠ BRÜCKEN...
Un champ d’application plus restreint peut être spécifié et s’appliquera de la même manière à toutes les actions :
$ echo ' Koeffizienten != Bruecken... ' | srgn -Sgu ' bw{1,8}b '
Koeffizienten != BRÜCKEN...
Les limites des mots sont obligatoires, sinon Koeffizienten
correspond à Koeffizi
et enten
. Notez que les points suivants ne peuvent pas être, par exemple, compressés. La portée requise de .
interférerait avec celui donné. Une tuyauterie régulière résout ce problème :
$ echo ' Koeffizienten != Bruecken... ' | srgn -Sgu ' bw{1,8}b ' | srgn -s ' . '
Koeffizienten != BRÜCKEN.
Remarque : l'échappement des expressions régulières ( .
) peut être contourné en utilisant la portée littérale. L'action de remplacement spécialement traitée est également composable :
$ echo ' Mooood: ????!!! ' | srgn -s ' p{Emoji} ' ' ? '
Mooood: ?!!!
Les émojis sont d’abord tous remplacés, puis pressés. Remarquez que rien d'autre n'est compressé.
Les scopes sont le deuxième concept moteur de srgn
. Dans le cas par défaut, la portée principale est une expression régulière. La section actions a présenté ce cas d'utilisation de manière assez détaillée, elle n'est donc pas répétée ici. Il est donné comme premier argument positionnel.
srgn
étend cela grâce à des portées préparées et sensibles à la grammaire du langage, rendues possibles grâce à l'excellente bibliothèque tree-sitter
. Il offre une fonctionnalité de requêtes, qui fonctionne un peu comme une correspondance de modèles avec une structure de données arborescente.
srgn
est fourni avec une poignée de ces requêtes les plus utiles. Grâce à son API détectable (soit sous forme de bibliothèque, soit via CLI, srgn --help
), on peut connaître les langages pris en charge et les requêtes préparées disponibles. Chaque langage pris en charge est livré avec une trappe d'évacuation, vous permettant d'exécuter vos propres requêtes ad hoc personnalisées. La hachure se présente sous la forme de --lang-query
, où lang
est un langage tel que python
. Voir ci-dessous pour en savoir plus sur ce sujet avancé.
Note
Les étendues de langage sont appliquées en premier , donc quelle que soit l'expression régulière, c'est-à-dire la portée principale que vous transmettez, elle fonctionne individuellement sur chaque construction de langage correspondante.
Cette section montre des exemples pour certaines des requêtes préparées .
unsafe
(Rust) L'un des avantages du mot-clé unsafe
dans Rust est sa « grepability ». Cependant, un rg 'unsafe'
fera bien sûr apparaître toutes les correspondances de chaînes ( rg 'bunsafeb'
aide dans une certaine mesure), pas seulement celles du mot-clé réel du langage Rust. srgn
aide à rendre cela plus précis. Par exemple:
// Oh no, an unsafe module!
mod scary_unsafe_operations {
pub unsafe fn unsafe_array_access ( arr : & [ i32 ] , index : usize ) -> i32 {
// UNSAFE: This function performs unsafe array access without bounds checking
* arr . get_unchecked ( index )
}
pub fn call_unsafe_function ( ) {
let unsafe_numbers = vec ! [ 1 , 2 , 3 , 4 , 5 ] ;
println ! ( "About to perform an unsafe operation!" ) ;
let result = unsafe {
// Calling an unsafe function
unsafe_array_access ( & unsafe_numbers , 10 )
} ;
println ! ( "Result of unsafe operation: {}" , result ) ;
}
}
peut être recherché comme