检查第一个字符与最后一个字符是否相同?

检查第一个字符与最后一个字符是否相同?

我对此有一个想法,我们必须使用grep反向引用,但这是我能得到的最接近的结果

grep "^[a-zA-z]\$[a-zA-z]\

我的问题是我不确定如何检查第一个字符 == 到最后一个字符?

答案1

你需要

grep -E '^([a-zA-Z]).*\1$'

捕获其中的第一个字符(...)并使用其反向引用作为最后一个字符并跳过 之间的所有其他内容.*。这-E开关使能扩展正则表达式匹配,这样我们就不需要在我们的grep命令范围内逃脱捕获组,但是;您还可以执行以下操作并提高可移植性:

grep '^\([a-zA-Z]\).*\1$'

如果您只想输出包含单个字符的行(但这也称为第一个和最后一个字符相同),您可以选择定义它的存在,请尝试:

grep -- '^\([a-zA-Z]\)\(.*\1\)\{0,1\}$'

\{0,1\}不匹配或只匹配一次图案 .*\1多于。

或者在每个上都匹配这个单身的像上面这样的字节字符是:

grep -- '^\(.\)\(.*\1\)\{0,1\}$'

默认情况下grep使用--basic-regexp(Basic-Regular-Expression, BRE) 模式匹配,其中元字符如?, +, {, |, (, 和)失去其特殊含义并按字面​​匹配,要将它们用作正则表达式,我们需要使用转义类型\?, \+, \{\|\(, 和\)或 只是切换模式匹配到 ERE -E(但请注意,POSIX ERE 没有反向引用)。


检查字符串的长度是否相同:

grep -- '^\([a-zA-Z]\{N-HERE\}\)\(.*\1\)\{0,1\}$'

3字符长度:

grep -- '^\([a-zA-Z]\{3\}\)\(.*\1\)\{0,1\}$'

再次,如上所述,这将返回类似的行3一般来说)字符长度xxx,如果你不需要这些,更改为:

grep -- '^\([a-zA-Z]\{3\}\).*\1$'

答案2

如果处理文本行,awk是最明显的:

awk 'length>1 && substr($0,1,1)==substr($0,length,1)' file

如果这是一个 shell 变量:

case $var in ''|?) echo no;; "${var#"${var%?}"}"*) echo yes;; *) echo no;; esac
[ "${#var}" -gt 1 ] && [ "${var%"${var#?}"}" = "${var#"${var%?}"}" ]

答案3

当 shell 可以轻松执行测试时,为什么要使用像grep或 这样的外部实用程序?awk

假设字符串至少包含两个字符 - 如果字符串仅包含一个字符,有人可能会认为最后一个字符等于第一个字符,但我认为OP的问题是关于包含两个或更多字符的字符串。

#!/bin/bash

# set -x
# set -v

is_match() {
   (( ${#1} < 2 )) && return 1
   [[ "${1:0:1}" != "${1: -1}" ]] && return 1
   return 0
}

check() {
   if is_match "$1"
   then
      echo "\"$1\" is a match"
   else
      echo "\"$1\" is not a match"
   fi
}

check ""
check "a?"
check "a*"
check "a"
check "cdc"
check "abbba"
check "é"
check "étéa"
check "été"

输出:

"" is not a match
"a?" is not a match
"a*" is not a match
"a" is not a match
"cdc" is a match
"abbba" is a match
"é" is not a match
"étéa" is not a match
"été" is a match

答案4

将当前记录拆分为空字符串,然后将第一个字段与最后一个字段进行比较

$ echo "racecar" \
| gawk -F "" '$1 == $NF'
racecar
  • 请注意,此工件仅适用于GNU awk@Ed Morton 所指出的情况。

相关内容