소스 코드 구문을 이해하고 검색 외에 조작을 허용하는 grep
과 유사한 도구입니다.
grep
과 마찬가지로 정규 표현식은 핵심 기본 요소입니다. grep
과 달리 추가 기능을 사용하면 조작 옵션을 통해 더 높은 정밀도를 얻을 수 있습니다. 이를 통해 srgn
정규식 차원과 IDE 도구( 모두 이름 바꾸기 , 모든 참조 찾기 등)에 따라 작동할 수 있으며 이를 보완할 수 있습니다.
srgn
수행할 작업 (있는 경우)을 중심으로 구성되며, 선택적으로 언어 문법 인식 범위 내에서만 작동합니다. 기존 도구의 관점에서 보면 단순성을 목표로 하는 tr
, sed
, ripgrep 및 tree-sitter
혼합한 것으로 생각하십시오. 정규 표현식과 작업 중인 언어의 기본 사항을 알고 있으면 좋습니다. .
팁
여기에 표시된 모든 코드 조각은 실제 srgn
바이너리를 사용하는 단위 테스트의 일부로 확인됩니다. 여기에 표시된 내용은 작동이 보장됩니다.
가장 간단한 srgn
사용법은 tr
과 유사하게 작동합니다.
$ echo ' Hello World! ' | srgn ' [wW]orld ' ' there ' # replacement
Hello there !
정규식 패턴 '[wW]orld'
( 범위 )에 대한 일치 항목은 두 번째 위치 인수로 대체됩니다( 작업 ). 0개 이상의 작업을 지정할 수 있습니다.
$ 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 !
교체는 항상 먼저 수행되고 위치별로 지정됩니다. 다른 작업은 명령줄 플래그 이후에 적용되고 제공됩니다.
마찬가지로, 둘 이상의 범위를 지정할 수 있습니다. 정규식 패턴 외에도 소스 코드의 구문 요소 에 대한 범위를 지정하는 언어 문법 인식 범위를 지정할 수 있습니다(예를 들어 "Python의 모든 class
정의 본문"을 생각해 보세요). ). 둘 다 제공되면 정규식 패턴은 첫 번째 언어 범위 내에서만 적용됩니다 . 이를 통해 일반 정규 표현식으로는 일반적으로 불가능했던 정밀한 검색 및 조작이 가능하며 IDE의 모두 이름 바꾸기 와 같은 도구와는 다른 차원을 제공합니다.
예를 들어, 다음과 같은 (무의미한) Python 소스 파일을 고려해보세요:
"""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 )
다음을 사용하여 검색할 수 있습니다.
$ cat birds.py | srgn --python ' class ' ' age '
11: age: int
15: self.age += 1
문자열 age
Python class
정의 내 에서만 검색되고 발견되었습니다(예를 들어 age
도 발생하고 바닐라 grep
에서 고려 대상에서 제외하는 것이 거의 불가능한 register_bird
와 같은 함수 본문에서는 검색되지 않습니다). 기본적으로 이 '검색 모드'는 줄 번호도 인쇄합니다. 작업이 지정되지 않은 경우 검색 모드로 들어가고 --python
과 같은 언어에 1이 제공됩니다. 'ripgrep이지만 구문 언어 요소가 있는' 것과 같다고 생각하세요.
검색은 여러 줄에 걸쳐 수행될 수도 있습니다. 예를 들어 독스트링이 없는 메서드( class
내의 def
라고도 함)를 찾는 경우입니다.
$ cat birds.py | srgn --python ' class ' ' def .+:ns+[^"s]{3} ' # do not try this pattern at home
13: def celebrate_birthday(self):
14: print("?")
이것이 어떻게 from_egg
(문서 문자열 있음) 또는 register_bird
(메서드가 아님, def
외부 class
)가 표면화되지 않는지 확인하세요.
언어 범위 자체도 여러 번 지정할 수 있습니다. 예를 들어 Rust 코드 조각에서
pub enum Genre {
Rock ( Subgenre ) ,
Jazz ,
}
const MOST_POPULAR_SUBGENRE : Subgenre = Subgenre :: Something ;
pub struct Musician {
name : String ,
genres : Vec < Subgenre > ,
}
여러 항목을 외과적으로 드릴다운할 수 있습니다.
$ cat music.rs | srgn --rust ' pub-enum ' --rust ' type-identifier ' ' Subgenre ' # AND'ed together
2: Rock(Subgenre),
모든 기준과 일치하는 행만 반환되며 모든 조건 사이에서 논리적 으로 작동합니다. 조건은 왼쪽에서 오른쪽으로 평가되므로 일부 조합이 의미가 없게 됩니다. 예를 들어 Python doc-strings
내 에서 Python class
본문을 검색하면 일반적으로 아무것도 반환되지 않습니다. 그러나 그 반대는 예상대로 작동합니다.
$ cat birds.py | srgn --py ' class ' --py ' doc-strings '
8: """A bird!"""
19: """Create a bird from an egg."""
class
본문 외부의 독스트링은 표시되지 않습니다!
-j
플래그는 이 동작을 왼쪽에서 오른쪽으로 교차하는 것에서 모든 쿼리를 독립적으로 실행하고 결과를 결합하는 것으로 변경하여 한 번에 여러 방법으로 검색할 수 있도록 합니다.
$ 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!
bird[^s]
패턴은 "주석 내의 독스트링"뿐만 아니라 주석 이나 독스트링 내부에서도 발견되었습니다.
표준 입력이 제공되지 않으면 srgn
다음 저장소에서 관련 소스 파일을 자동으로 찾는 방법을 알고 있습니다.
$ 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
현재 디렉터리를 재귀적으로 탐색하여 파일 확장자와 shebang 줄을 기반으로 파일을 찾고 매우 빠른 속도로 처리합니다. 예를 들어, srgn --go strings 'd+'
M3의 12개 코어에서 3초 이내에 Kubernetes 코드 베이스 내 Go 코드 ~3,000,000줄의 리터럴 Go 문자열에서 ~140,000개의 숫자 실행을 모두 찾아서 인쇄합니다. 많은 파일 작업에 대한 자세한 내용은 아래를 참조하세요.
범위와 작업은 거의 임의로 결합할 수 있습니다. 하지만 많은 조합은 유용하지 않거나 의미가 없습니다. 예를 들어 다음 Python 코드 조각을 고려해보세요(다른 지원 언어를 사용하는 예는 아래 참조).
"""GNU module."""
def GNU_says_moo ():
"""The GNU function -> say moo -> ✅"""
GNU = """
GNU
""" # the GNU...
print ( GNU + " says moo" ) # ...says moo
다음 명령이 실행됩니다.
cat gnu.py | srgn --titlecase --python ' doc-strings ' ' (?' ' $1: GNU ? is not Unix '
해당 호출의 구조는 다음과 같습니다.
--titlecase
(작업)는 범위 내에서 발견된 모든 것을 제목으로 표시합니다.
--python 'doc-strings'
(범위)는 Python 언어 문법에 따라 docstring으로 범위를 지정합니다(즉, 고려만 함).
'(? (범위)는 이전 옵션에 의해 이미 범위가 지정된 것만 확인하고 범위를 더 좁힙니다. 이전 범위를 확장할 수는 없습니다. 정규식 범위는 모든 언어 범위 뒤에 적용됩니다.
(? 는 부정형 뒤돌아보기 구문으로, 이 고급 기능을 사용할 수 있는 방법을 보여줍니다.
The
접두사가 붙은 GNU
문자열은 고려되지 않습니다.
'$1: GNU ? is not Unix'
(액션)는 일치하는 각 항목(즉, 범위 내에 있는 것으로 확인된 각 입력 섹션)을 이 문자열로 대체 합니다. 일치하는 항목은 Python 독스트링 내에서만 '(? 패턴입니다. 특히 이 대체 문자열은 다음을 보여줍니다.
$1
사용한 동적 변수 바인딩 및 대체. (? 캡처되지 않기 때문에 ([az]+)
입니다.
이 명령은 여러 범위(언어 및 정규식 패턴)와 여러 작업(교체 및 제목 표시)을 사용합니다. 결과는 다음과 같습니다
"""Module: GNU ? Is Not Unix."""
def GNU_says_moo ():
"""The GNU function -> say moo -> ✅"""
GNU = """
GNU
""" # the GNU...
print ( GNU + " says moo" ) # ...says moo
변경 사항은 다음으로 제한됩니다.
- """GNU module."""
+ """Module: GNU ? Is Not Unix."""
def GNU_says_moo():
"""The GNU -> say moo -> ✅"""
경고
srgn
이 베타 버전(주 버전 0)인 동안 안전하게 복원할 수 있는 파일만 (재귀적으로) 처리해야 합니다.
검색 모드는 파일을 덮어쓰지 않으므로 항상 안전합니다.
도구의 전체 도움말 출력은 아래를 참조하세요.
메모
지원되는 언어는
릴리스에서 사전 빌드된 바이너리를 다운로드합니다.
이 크레이트는 cargo-binstall
와 호환되는 형식으로 바이너리를 제공합니다:
cargo install cargo-binstall
실행(시간이 걸릴 수 있음)cargo binstall srgn
실행(GitHub에서 사전 빌드된 바이너리를 다운로드하는 몇 초)이러한 단계는 CI에서 테스트되었으므로 작동이 보장됩니다. 도구가 소스에서 컴파일하는 것으로 대체되므로 플랫폼에 사용할 수 있는 사전 빌드된 바이너리가 없는 경우에도 작동합니다.
다음을 통해 수식을 사용할 수 있습니다.
brew install srgn
불안정을 통해 사용 가능:
nix-shell -p srgn
AUR을 통해 이용 가능합니다.
포트를 사용할 수 있습니다:
sudo port install srgn
모든 GitHub Actions 러너 이미지에는 cargo
사전 설치되어 있으며, cargo-binstall
편리한 GitHub Action을 제공합니다.
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
위의 내용은 컴파일이 필요하지 않으므로 총 5초 안에 완료됩니다. 자세한 내용은 CI에 대한 cargo-binstall
의 조언을 참조하세요.
Linux에서는 gcc
작동합니다.
macOS에서는 clang
사용하세요.
Windows에서는 MSVC가 작동합니다.
설치 시 "C++를 사용한 데스크톱 개발"을 선택합니다.
cargo install srgn
실행 cargo add srgn
자세한 내용은 여기를 참조하세요.
쉘 완성 스크립트에는 다양한 쉘이 지원됩니다. 예를 들어 ZSH에서 완료하려면 ~/.zshrc
에 eval "$(srgn --completions zsh)"
추가합니다. 대화형 세션은 다음과 같습니다.
이 도구는 범위 와 작업을 중심으로 설계되었습니다. 범위는 처리할 입력 부분을 좁힙니다. 그런 다음 작업이 처리를 수행합니다. 일반적으로 범위와 작업은 모두 구성 가능하므로 각각 둘 이상이 전달될 수 있습니다. 둘 다 선택 사항입니다(그러나 아무 조치도 취하지 않는 것은 의미가 없습니다). 범위를 지정하지 않으면 전체 입력이 범위 내에 있음을 의미합니다.
동시에 일반 tr
과 상당한 중복이 있습니다. 이 도구는 가장 일반적인 사용 사례에서 긴밀하게 대응하도록 설계되었으며 필요한 경우에만 그 이상을 사용합니다.
가장 간단한 조치는 교체입니다. tr
및 일반 인체공학과의 호환성을 위해 특별히 액세스됩니다(옵션이 아닌 인수로). 다른 모든 작업은 플래그로 제공되거나 값을 취하는 옵션으로 제공됩니다.
예를 들어 간단한 단일 문자 대체는 tr
에서처럼 작동합니다.
$ echo ' Hello, World! ' | srgn ' H ' ' J '
Jello, World!
첫 번째 인수는 범위(이 경우 리터럴 H
)입니다. 이것과 일치하는 모든 것은 처리 대상입니다(이 경우 두 번째 인수인 J
로 대체됨). 그러나 tr
에서와 같이 문자 클래스에 대한 직접적인 개념은 없습니다 . 대신 기본적으로 범위는 정규식 패턴이므로 해당 클래스를 비슷한 효과로 사용할 수 있습니다.
$ echo ' Hello, World! ' | srgn ' [a-z] ' ' _ '
H____, W____!
교체는 기본적으로 전체 일치 항목에서 탐욕스럽게 발생합니다( tr
의 [:alnum:]
연상시키는 UTS 문자 클래스에 유의하세요).
$ echo ' ghp_oHn0As3cr3T!! ' | srgn ' ghp_[[:alnum:]]+ ' ' * ' # A GitHub token
*!!
예를 들어 둘러보기와 같은 고급 정규식 기능이 지원됩니다.
$ echo ' ghp_oHn0As3cr3T ' | srgn ' (?<=ghp_)[[:alnum:]]+ ' ' * '
ghp_*
고급 패턴에는 특정 안전 및 성능 보장이 없으므로 안전하게 사용하도록 주의하세요. 사용하지 않으면 성능에 영향을 주지 않습니다.
대체는 단일 문자로 제한되지 않습니다. 예를 들어 다음 인용문을 수정하려면 임의의 문자열이 될 수 있습니다.
$ echo ' "Using regex, I now have no issues." ' | srgn ' no issues ' ' 2 problems '
"Using regex, I now have 2 problems."
이 도구는 유니코드를 완전히 인식하며 특정 고급 문자 클래스에 대한 유용한 지원을 제공합니다.
$ echo ' Mood: ? ' | srgn ' ? ' ' ? '
Mood: ?
$ echo ' Mood: ???? :( ' | srgn ' p{Emoji_Presentation} ' ' ? '
Mood: ???? :(
교체는 정규식 캡처 그룹을 통해 사용할 수 있는 변수를 인식합니다. 캡처 그룹에는 번호를 매기거나 선택적으로 이름을 지정할 수 있습니다. 0번째 캡처 그룹은 전체 일치 항목에 해당합니다.
$ 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.
예를 들어, 보다 고급 사용 사례는 명명된 캡처 그룹을 사용한 코드 리팩토링입니다(아마도 더 유용한 것을 생각해낼 수 있습니다...).
$ echo ' let x = 3; ' | srgn ' let (?[a-z]+) = (?.+); ' ' const $var$var = $expr + $expr; '
const xx = 3 + 3;
Bash에서와 마찬가지로 중괄호를 사용하여 바로 인접한 콘텐츠와 변수를 구분합니다.
$ 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)
대체가 단지 정적 문자열인 것을 보면 그 유용성은 제한적입니다. 여기가 tr
의 비밀 소스가 일반적으로 작용하는 곳입니다. 두 번째 위치에서도 유효한 문자 클래스를 사용하여 첫 번째 멤버에서 두 번째 멤버로 깔끔하게 변환하는 것입니다. 여기서 해당 클래스는 대신 정규식이며 첫 번째 위치(범위)에서만 유효합니다. 상태 머신인 정규 표현식은 tr
에서 두 번째(선택적) 인수인 '문자 목록'과 일치하는 것이 불가능합니다. 그 개념은 창밖이고 유연성도 상실되었습니다.
대신, 모두 수정된 제안된 작업이 사용됩니다. tr
의 가장 일반적인 사용 사례를 살펴보면 제공된 작업 세트가 사실상 모든 사례를 포괄한다는 것을 알 수 있습니다! 해당 사용 사례가 다루어지지 않은 경우 자유롭게 문제를 제기하세요.
다음 작업으로 넘어갑니다.
입력에서 발견된 모든 것을 제거합니다. tr
과 동일한 플래그 이름입니다.
$ echo ' Hello, World! ' | srgn -d ' (H|W|!) '
ello, orld
메모
기본 범위는 입력 내용 전체를 일치시키는 것이므로 범위 없이 삭제를 지정하면 오류가 발생합니다.
범위와 일치하는 문자의 반복을 단일 발생으로 압축합니다. tr
과 동일한 플래그 이름입니다.
$ echo ' Helloooo Woooorld!!! ' | srgn -s ' (o|!) '
Hello World!
문자 클래스가 전달되면 해당 클래스의 모든 멤버는 먼저 발생한 클래스 멤버에 압착됩니다.
$ echo ' The number is: 3490834 ' | srgn -s ' d '
The number is: 3
매칭에 대한 욕심은 수정되지 않으니 주의하세요.
$ echo ' Winter is coming... ??? ' | srgn -s ' ?+ '
Winter is coming... ???
메모
패턴이 태양의 전체 흐름과 일치하므로 짜낼 것이 없습니다. 여름이 우세합니다.
사용 사례에서 요구하는 경우 탐욕을 반전시킵니다.
$ echo ' Winter is coming... ??? ' | srgn -s ' ?+? ' ' ☃️ '
Winter is coming... ☃️
메모
다시 말하지만, 삭제와 마찬가지로 명시적인 범위 없이 압착을 지정하는 것은 오류입니다. 그렇지 않으면 전체 입력이 압축됩니다.
tr
사용의 상당 부분이 이 범주에 속합니다. 매우 간단합니다.
$ echo ' Hello, World! ' | srgn --lower
hello, world!
$ echo ' Hello, World! ' | srgn --upper
HELLO, WORLD!
$ echo ' hello, world! ' | srgn --titlecase
Hello, World!
정규화 형식 D에 따라 입력을 분해한 다음 마크 범주의 코드 포인트를 삭제합니다(예제 참조). 이는 대략적으로 멋진 캐릭터를 취하고, 매달린 부분을 떼어내고, 그것들을 버리는 것을 의미합니다.
$ 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
mgła
"원자"이므로 분해할 수 없기 때문에 NFD의 범위를 벗어납니다(적어도 ChatGPT가 내 귀에 속삭이는 내용입니다).
이 작업은 다중 문자 ASCII 기호를 적절한 단일 코드 포인트, 기본 유니코드 대응 항목으로 바꿉니다.
$ echo ' (A --> B) != C --- obviously ' | srgn --symbols
(A ⟶ B) ≠ C — obviously
또는 수학에만 관심이 있다면 범위 지정을 활용하세요.
$ echo ' A <= B --- More is--obviously--possible ' | srgn --symbols ' <= '
A ≤ B --- More is--obviously--possible
ASCII 기호와 대체 기호 사이에는 1:1 대응이 있으므로 효과는 가역적입니다. 2 :
$ echo ' A ⇒ B ' | srgn --symbols --invert
A => B
현재 지원되는 기호 세트는 제한되어 있지만 더 많은 기호가 추가될 수 있습니다.
이 작업은 독일어 특수 문자(ae, oe, ue, ss)의 대체 철자를 해당 기본 버전(ä, ö, ü, ß)으로 대체합니다 3 .
$ echo ' Gruess Gott, Neueroeffnungen, Poeten und Abenteuergruetze! ' | srgn --german
Grüß Gott, Neueröffnungen, Poeten und Abenteuergrütze!
이 작업은 단어 목록을 기반으로 합니다(이진 파일이 너무 많이 부풀어오르는 경우 german
기능 없이 컴파일). 위 예의 다음 기능에 유의하세요.
Poeten
순진하고 실수로 Pöten
으로 변환되는 대신 그대로 유지되었습니다.Abenteuergrütze
합리적인 단어 목록에서 찾을 수 없지만 그럼에도 불구하고 적절하게 처리되었습니다.Abenteuer
Abenteür
로 잘못 변환되지 않고 그대로 유지되었습니다.Neueroeffnungen
구성 단어( neu
, Eröffnungen
)가 소유하지 않은 ue
요소를 몰래 형성하지만 여전히 올바르게 처리됩니다(대소문자가 일치하지 않음에도 불구하고).요청 시 이름에 유용할 수 있으므로 강제로 교체할 수 있습니다.
$ echo ' Frau Loetter steht ueber der Mauer. ' | srgn --german-naive ' (?<=Frau )w+ '
Frau Lötter steht ueber der Mauer.
긍정적인 예측을 통해 인사말만 범위가 지정되어 변경되었습니다. Mauer
그대로 유지되었지만 ueber
처리되지 않았습니다. 두 번째 패스에서는 이 문제를 해결합니다.
$ echo ' Frau Loetter steht ueber der Mauer. ' | srgn --german-naive ' (?<=Frau )w+ ' | srgn --german
Frau Lötter steht über der Mauer.
메모
일부 "부모"와 관련된 옵션 및 플래그에는 부모 이름이 접두어로 붙고, 주어지면 부모를 암시 하므로 후자는 명시적으로 전달할 필요가 없습니다. 이것이 --german-naive
의 이름이 그대로 지정되고 --german
전달할 필요가 없는 이유입니다.
clap
하위 명령 연결을 지원하면 이 동작이 변경될 수 있습니다.
이 간단한 도구는 언어 컨텍스트 없이 작동하기 때문에 일부 분기를 결정할 수 없습니다. 예를 들어 Busse
(버스)와 Buße
(고행)는 모두 합법적인 단어입니다. 기본적으로 합법적인 경우 교체가 탐욕스럽게 수행되지만(결국 srgn
의 요점) 이 동작을 전환하기 위한 플래그가 있습니다.
$ echo ' Busse und Geluebte ' | srgn --german
Buße und Gelübte
$ echo ' Busse ? und Fussgaenger ?♀️ ' | srgn --german-prefer-original
Busse ? und Fußgänger ?♀️
무의미한 작업(삭제 등)이 아닌 이상 대부분의 작업은 구성 가능합니다. 적용 순서는 고정되어 있으므로 지정된 플래그의 순서는 영향을 미치지 않습니다(필요한 경우 여러 파이프를 연결하는 것이 대안입니다). 교체는 항상 먼저 발생합니다. 일반적으로 CLI는 오용과 예상치 못한 일을 방지하도록 설계되었습니다. 예상치 못한 작업을 수행하는 것보다 충돌을 선호합니다(물론 주관적임). 기술적으로는 다양한 조합 이 가능하지만 무의미한 결과가 나올 수도 있습니다.
작업 결합은 다음과 같습니다.
$ echo ' Koeffizienten != Bruecken... ' | srgn -Sgu
KOEFFIZIENTEN ≠ BRÜCKEN...
더 좁은 범위를 지정할 수 있으며 모든 작업에 동일하게 적용됩니다.
$ echo ' Koeffizienten != Bruecken... ' | srgn -Sgu ' bw{1,8}b '
Koeffizienten != BRÜCKEN...
그렇지 않으면 Koeffizienten
이 Koeffizi
및 enten
과 일치하므로 단어 경계가 필요합니다. 예를 들어 후행 마침표를 압착할 수 없는 방법에 유의하세요. .
주어진 것을 방해할 것이다. 일반 배관을 사용하면 다음과 같은 문제가 해결됩니다.
$ echo ' Koeffizienten != Bruecken... ' | srgn -Sgu ' bw{1,8}b ' | srgn -s ' . '
Koeffizienten != BRÜCKEN.
참고: 정규식 이스케이프( .
)는 리터럴 범위 지정을 사용하여 피할 수 있습니다. 특별히 처리된 교체 작업도 구성 가능합니다.
$ echo ' Mooood: ????!!! ' | srgn -s ' p{Emoji} ' ' ? '
Mooood: ?!!!
이모티콘은 먼저 모두 교체된 다음 압착됩니다. 다른 어떤 것도 압착되지 않는지 확인하십시오.
범위는 srgn
의 두 번째 추진 개념입니다. 기본 경우 기본 범위는 정규식입니다. 작업 섹션에서는 이 사용 사례를 어느 정도 자세히 보여주었으므로 여기서는 반복하지 않습니다. 이는 첫 번째 위치 인수로 제공됩니다.
srgn
뛰어난 tree-sitter
라이브러리를 통해 가능해진 준비된 언어 문법 인식 범위를 통해 이를 확장합니다. 이는 트리 데이터 구조에 대한 패턴 일치와 매우 유사하게 작동하는 쿼리 기능을 제공합니다.
srgn
이러한 쿼리 중 가장 유용한 몇 가지 쿼리와 함께 번들로 제공됩니다. 검색 가능한 API(라이브러리 또는 CLI, srgn --help
)를 통해 지원되는 언어와 사용 가능한 준비된 쿼리를 알아볼 수 있습니다. 지원되는 각 언어에는 탈출구가 포함되어 있어 사용자가 직접 사용자 정의 임시 쿼리를 실행할 수 있습니다. 해치는 --lang-query
형식으로 제공됩니다. 여기서 lang
은 python
과 같은 언어입니다. 이 고급 주제에 대한 자세한 내용은 아래를 참조하세요.
메모
언어 범위가 먼저 적용되므로 전달하는 정규식(일명 기본 범위)이 무엇이든 일치하는 각 언어 구성에 대해 개별적으로 작동합니다.
이 섹션에서는 준비된 쿼리 중 일부에 대한 예를 보여줍니다.
unsafe
코드 찾기(Rust) Rust에서 unsafe
키워드의 장점 중 하나는 "grepability"입니다. 그러나 rg 'unsafe'
는 물론 실제 Rust 언어 키워드의 문자열뿐만 아니라 모든 문자열 일치( rg 'bunsafeb'
가 어느 정도 도움이 됨)를 표시합니다. srgn
이를 더욱 정확하게 만드는 데 도움이 됩니다. 예를 들어:
// 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 ) ;
}
}
다음과 같이 검색할 수 있습니다.