한 줄에 하나씩 여러 문자열이 포함된 파일이 있습니다. 나는 회문이 포함되어 있고 회문이 대괄호 사이에 있지 않은 경우에만 문자열을 찾아서 인쇄하고 싶습니다. 예:
abba[cdef]gh # print
abcd[effe]gh # do not print
현재 문자열이 회문인 경우 한 줄을 인쇄하는 한 줄 코드가 있습니다.
awk 'BEGIN { system("perl -lne \"print if length == 4 && reverse eq \\$_\" " ARGV[1]) }' words.txt
다음에서 수정됨여기.
나는 sed
대괄호 사이의 모든 것을 제거한 다음 나머지 회문을 평가하는 것을 고려하고 있습니다.
한 줄로 이 작업을 수행하는 방법에 대한 다른 아이디어가 있습니까?
답변1
3개 이상의 문자로 구성된 회문을 하나만 제외하고 모두 찾으려면 다음을 수행하십시오 [...]
.
$ echo 'cac[ada]abacab' | perl -nle '
while (/\[.*?\]|(?=(([^][])(?1)\2|[^][]?))./g) {
print $1 if length $1 >= 3
}'
cac
aba
bacab
aca
(단일 바이트 문자를 가정하고 -Mopen=locale
문자의 로케일 정의를 추가합니다.)
회문 일치의 핵심은 재귀 정규식입니다. 회문은 빈 문자열이나 단일 문자 또는 일치하는 문자 쌍과 그 사이에 있는 다른 회문과 일치합니다. 즉 ((.)(?1)\2|.?)
, (?1)
재귀 부분이 ( 의 첫 번째 부분과 일치합니다 . 단, 여기서는 ( 및 를 제외한 모든 문자 ) 로 ()
바꿉니다 ..
[^][]
]
[
매칭 시모두가 나타나면 /.../g
Perl은 첫 번째 발생 후 다음 발생을 검색하므로 in이 있으면 in을 먼저 찾은 다음 계속 검색 하기 때문에 in을 \[.*?\]|(([^][])(?1)\2|[^][]?)
찾지 못할 것입니다 . 따라서 여기서는 단일 문자( )가 문자의 시작 부분에 있는 경우 해당 문자 와 일치하는 조건을 일치시킵니다.bacab
abacab
aba
aba
(?=(palindrome)).
.
회문그런 다음 에서 캡처됩니다 $1
. 이는 해당 단일 문자를 계속 검색한다는 의미입니다.
엄밀히 말하면 s 를 건너뛰고 문자열의 모든 위치에서 가장 긴(3자 이상) 회문을 찾으 [...]
므로 찾지 못할 수도 있습니다.모두이벤트. 예를 들어 에서는 첫 번째 위치, 세 번째 위치, 두 번째 위치 에서는 ababa
검색되지만 첫 번째 위치에서는 검색되지 않습니다.ababa
bab
aba
aba
답변2
당신이 동의한 단 한 줄의 내용은 어떻습니까? 괄호 안에 있는 단어를 필드 구분 기호로 사용하세요.
perl -F'\[.*?\]' -le 'for $word (@F) {if ($word eq reverse $word) {print; break}}' file
일부 극단적인 경우는 여기에서 고려되지 않습니다.
- 문자열 길이를 고려하지 않습니다.
- 회문 번호를 찾지 못한 것 같습니다.이내에단어: 전체 단어는 회문이어야 합니다.
답변3
[...]
사전에 필터링할 수 있지만Lex와 같은 스캐너다음 줄을 사용하세요.
#!/usr/bin/env perl
use strict;
use warnings;
LINE: while (readline) { # for each line (files or stdin)
LEX: {
# skip any [] or [...] bits
redo LEX if m{ \G \[ [^\]]* \] }cgx;
# two or more not-[ not-vertical-whitespace (\r, \n) chars
if (m{ \G ([^\[\v]{2,}) }cgx) {
# palindrome? print the whole line
if ( $1 eq reverse $1 ) {
print;
next LINE;
}
# may be more to come...
redo LEX;
}
# advance the lexer a single character
redo LEX if m{ \G . }cgx;
# oh it's the end of the line as we know it
}
}
다양한 엣지 조건에 대한 확장된 테스트 사례가 있습니다.
% < input
abba[cdef]gh # print
abcd[effe]gh # do not print
[effe]f00f
asdf[]prinirp
a[]b[]edgegde
% perl palin < input
abba[cdef]gh # print
[effe]f00f
asdf[]prinirp
a[]b[]edgegde
%
이는 후행 주석이나 기타 입력을 무시하도록 쉽게 조정할 수 있습니다.