【问题标题】:Emacs regular expression: what \< and \> can do that \b cannot do?Emacs 正则表达式:\< 和 \> 可以做什么而 \b 不能做什么?
【发布时间】:2011-08-16 04:37:56
【问题描述】:

Regexp Backslash - GNU Emacs Manual 表示\&lt; 匹配单词的开头,\&gt; 匹配单词的结尾,\b 匹配单词的边界。 \b 就像在其他非 Emacs 正则表达式中一样。但似乎\&lt;\&gt; 是Emacs 正则表达式特有的。是否存在需要\&lt;\&gt; 而不是\b 的情况?例如,\bword\b 将与 \&lt;word\&gt; 匹配,唯一的区别是后者更具可读性。

【问题讨论】:

  • 它们也在 GNU Grep 和 Vim 中。
  • \&lt;\&gt; 来自最初的 vi,并一直保留至今。

标签: regex emacs word


【解决方案1】:

如果您假设它们的行为相同,您可能会得到意想不到的结果..
\b 的 \ 能做什么?
答案是\&lt;\&gt;显式...这个词的结尾!而且只有这个结尾!
\bis general....任何一个单词的结尾都会匹配...

GNU 运算符 * Word Operators

line="cat dog sky"  
echo "$line" |sed -n "s/\(.*\)\b\(.*\)/# |\1|\2|/p"
echo "$line" |sed -n "s/\(.*\)\>\(.*\)/# |\1|\2|/p"
echo "$line" |sed -n "s/\(.*\)\<\(.*\)/# |\1|\2|/p"
echo
line="cat  dog  sky"  
echo "$line" |sed -n "s/\(.*\)\b\(.*\)/# |\1|\2|/p"
echo "$line" |sed -n "s/\(.*\)\>\(.*\)/# |\1|\2|/p"
echo "$line" |sed -n "s/\(.*\)\<\(.*\)/# |\1|\2|/p"
echo
line="cat  dog  sky  "  
echo "$line" |sed -n "s/\(.*\)\b\(.*\)/# |\1|\2|/p"
echo "$line" |sed -n "s/\(.*\)\>\(.*\)/# |\1|\2|/p"
echo "$line" |sed -n "s/\(.*\)\<\(.*\)/# |\1|\2|/p"
echo

输出

# |cat dog |sky|
# |cat dog| sky|
# |cat dog |sky|

# |cat  dog  |sky|
# |cat  dog|  sky|
# |cat  dog  |sky|

# |cat  dog  sky|  |
# |cat  dog  sky|  |
# |cat  dog  |sky  |

【讨论】:

    【解决方案2】:

    在我看来,\&lt;.*?\&gt; 将只匹配一系列单词字符,而 \b.*?\b 将匹配一系列单词字符或一系列非单词字符,因为它也可以接受单词的结尾,并且然后一个的开始。如果你强迫两者之间的表达是一个词,它们的行为确实是一样的。

    当然,您可以使用\b\w\w\b 复制\&lt;\&gt; 的行为。所以我想答案是肯定的,它主要是为了可读性。话说回来,这不是正则表达式中大多数转义字符的用途吗?

    【讨论】:

    • 转义字符 `\` 绝不是为了可读性。它用于区分 regex operator 和同一字形的 literal 字符
    • @fred - 我的意思是转义字符,如\w\d(不是\ 本身)通常可以替换为字符类的其他字符,如@987654330 @.
    • Daniel: \&lt;.*\&gt; 将匹配任何以单词字符为界的字符串。 .* 是贪心的,所以匹配尽可能多的任意字符。要仅匹配单个单词,您可以使用非贪婪变体:\&lt;.*?\&gt;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-17
    • 2011-08-23
    • 2011-05-31
    • 2011-10-24
    • 2020-07-09
    • 1970-01-01
    相关资源
    最近更新 更多