如何匹配一些用空格括起来或来自开头或结尾的字符串?
我需要匹配-someword
以下句子:word1 -someword word2
, -someword word1
, word1 -someword
, -someword
。并且句子中不需要匹配:s-someword
,-somewordd
我尝试用正则表达式 grep 上面的内容grep -r [^ ]-someword[$ ]
(即之前-someword
必须是空格或-someword
必须开始句子,之后-someword
必须是空格或-someword
必须结束句子),但它什么也没找到。
答案1
尝试:
grep -w -e -someword
从man grep
:
-w, --word-正则表达式
Select only those lines containing matches that form whole words. The test is that the matching substring must either be at the beginning of the line, or preceded by a non-word constituent character. Similarly, it must be either at the end of the line or followed by a non-word constituent character. Word-constituent characters are letters, digits, and the underscore. This option has no effect if -x is also
-someword
请注意,如果它被除空格之外的其他非字母数字字符包围,例如#
或,它也会匹配,
。如果你想确保它被包围仅有的通过空格或行首/行尾,您可以使用:
egrep '(^|[[:space:]])-someword([[:space:]]|$)'
# Which is equivalent to:
grep -E '(^|[[:space:]])-someword([[:space:]]|$)'
# Or without extended regex:
grep '\(^\|[[:space:]]\)-someword\([[:space:]]\|$\)'
答案2
您可以使用以下内容来避免复杂的正则表达式。它匹配-someword
开头有空格、-someword
中间某处两侧有空格或-someword
末尾有空格的任何行:
grep -e '^-someword ' -e ' -someword ' -e ' -someword$'
这一切都假设这-someword
是一个不包含任何正则表达式中特殊字符的字符串。如果是,则必须重写字符串以匹配这些文字字符,例如,通过在模式中转义它们。
如果您还想匹配只包含字符串的行-someword
,请添加-e '^-someword$'
.
如果“空格”的意思是“空白字符”,其中包括制表符和空格,则使用 更改模式中的文字空格[[:blank:]]
。如果您需要匹配更广泛的类似空格的字符,例如垂直制表符和回车符,请改用[[:space:]]
。
答案3
其正则表达式模式是(https://regexr.com/7b8g0):
(\s|^)-someword(\s|$)
很多 shell 都会对这些感到害怕,()\|
所以你必须稍微修改一下引号和转义符。例如,fish 似乎喜欢,\\s
但 zsh 喜欢\s
。
使用 ripgrep 和 Fish,实现起来非常容易:
$ bat word.txt --style=numbers
1 word1 -someword word2
2 -someword word1
3 word1 -someword
4 -someword
5 s-someword
6 -somewordd
7 \s-someword
$ bat word.txt | rg '(\\s|^)-someword(\\s|$)' --only-matching --line-number
1: -someword
2:-someword
3: -someword
4:-someword
$ bat word.txt | rg '(\\s|^)-someword(\\s|$)' --line-number -v
5:s-someword
6:-somewordd
7:\s-someword
(我添加了\s-someword
和-v
来解决评论中的一些问题。)
请注意,空格成为匹配的一部分。要在正则表达式中解决这个问题,您必须在周围添加一个捕获组-someword
(简单),然后告诉rg
返回第一个组(pffft ...)。
因为 grep 很古老,所以默认情况下它不会处理这种“高级”正则表达式语法。您需要添加-E
.
$ bat word.txt | grep -E '(\\s|^)(-someword)(\\s|$)' -n
1:word1 -someword word2
2:-someword word1
3:word1 -someword
4:-someword
$ bat word.txt | grep -v -E '(\\s|^)(-someword)(\\s|$)' -n
5:s-someword
6:-somewordd
7:\s-someword
坦率地说,如果您生活在以 2 开头的年份,那么无论如何您都应该使用grep
别名grep -E
。或者只是使用rg
.