我们如何去检验是否存在回文
sed命令能够记住匹配的子样式,称为反向引用,我们可以按照这个方式来解决回文问题
sed -n ‘/\(.\)\1/p’ filename
\()\的作用是记录()中的子串,上面的语句中还有一个. 是sed用于匹配单个字符的正则表达式
\1 对应() 中匹配的第一处内容, \2对应第二处匹配,因此我们就记录多个() 所匹配的内容 ()以\(\)的形式出现,表明不是普通的字符
sed会打印出.替换的正则表达式的字符两次
那么多回文,可能出现具有奇数个字符的情况,包含奇数长度的回文的正则表达式类似如下的形式,
‘/\(.\).\1/p’
我们额外加了一个字符 .
我们来编写这个回文脚本
if [$# -ne 2];
then
echo “Usage: $0 filename string_lenth”
exit -1
fi
filename=$1
basepattern=’/^\(.\)’
count=$(($2/2))
for((i=1;i<$count;i++))
do
basepattern=$basepattern’\(.\)’;
done
if [ $(( $2 % 2)) -ne 0 ];
then
basepattern=$basepattern ‘.’ ;
fi
for((count;count>0;count–))
do
basepattern=$basepattern’\'”$count” ;
done
basepattern=$basepattern’$/p’
sed -n “$basepattern” $filename
这样这个脚本可以直接使用了
具体的原理在于
想要匹配一个字符,并且进行反向的引用
使用 \(.\) 匹配单个字符,在用\1引用
匹配双字节,使用
sed ‘/\(.\)\1/p’
为了指明必须从行首开始匹配,我们加入了行首的标记
于是,上面的命令变为了sed ‘/^\(.\)\1/p’ /p可以帮助我们打印匹配的内容
匹配4个字符的回文
sed ‘/^\(.\)\(.\)\2\1/p’
我们用了2个 \(.\) 匹配记录回文中前两个字符, \2 \1会进行反向的引用
上面的脚本中,使用了一个被称为 basepattern的变量,包含了用于sed脚本的部分内容
basepattern最初初始化为basepattern=’/^\(.\)’ 对应匹配一个单字符, for循环拼接 \(.\)和baseoattern
循环的次数是回文长度的一般,最后,为了支持奇数长度的回文,在正则表达式和反向引用之间加上了一个可选的字符 (.)
这样,创建用于匹配回文的sed匹配的样式,这个匹配样式可以用来从字典文件中找出回文
我们使用for循环生成sed匹配样式,其实sed还可以自动的生成,但是有点难理解
于是先行暂停
获取到一个文本的倒序,其实unix提供了一个单独的rev的命令,
rev命令接收一个文件或者stdin作为输入,并且逆序打印出每一行的内容
比如,我们进行逆序的打印
string=”malayalam”
if[[ “String”==”$(echo $string | rev)” ]];
then
echo “Palidrome”
else
echo ‘Not palindrome”
fi
rev将所有的单词进行翻转
利用rev和tac的合作
sentence=’this is line from sentence’
echo $sentence | rev | tr ‘ ‘ ‘\n’ | tac |tr ‘\n’ ‘ ‘ | rev
上面的命令,首先使用了rev来翻转所有的字符,然后使用tr将空格替换为 \n,这样,所有的单词就分割为了单一的行,然后通过tac将所有的行进行翻转,然后tr将翻转的行合并为单一的行
最后对合并后的单行,再一次的rev,实现了翻转