좋습니다. 이제 해야 할 일은 모든 주석 블록을 다음 형식으로 변환하는 것뿐입니다.
/**
*
*/
도착하다:
/*!
*/
/**
그러나 상용구 라이센스 형식을 유지해야 하기 때문에 다음 줄에는 "저작권"을 포함할 수 없다는 점에 유의하는 것이 중요합니다 .
정규식을 사용하면 쉽게 할 수 있을 것 같지만 그룹 캡처에 대해 잘 모르고 두 가지 대체를 수행해야 하기 때문에 어떻게 해야 할지 모르겠습니다. 나는 현재 Perl에서 (나쁜) 솔루션을 해킹하고 있지만 거기에서 적절하게 대체하는 방법을 모르겠습니다.
편집: 지금은 \/\*\*.*(?!Copyright)^\ *(?P<ast>\*).*(?=\*\/)//sm
, 필요한 기능이 있는데 캡처된 그룹만 어떻게 바꾸나요?
답변1
복잡성을 알 수 없는 단일 정규 표현식이 확실히 작업을 수행하는 반면, 이해하고 유지하기 더 쉬운 것은 아마도 한 줄씩 파서가 될 것입니다. 그러나 분명한 주의 사항은 주석과 같은 문자 문자열이 주석 처리되지 않은 코드 부분에서는 쉽게 난독화될 수 있습니다(CPAN에 이 언어에 대한 어휘 분석기가 있을 수 있습니다.구문 분석::MGC약간 공식적인 방식으로 이러한 작업을 수행합니다.)
#!/usr/bin/env perl
use strict;
use warnings;
my @comment;
# read stuff from standard input or files on argument line, whatever
LINE: while (<>) {
# assume this is a comment, start saving lines
if (m{^\s*/\*\*}) {
push @comment, $_;
next LINE;
}
if (@comment) {
push @comment, $_;
# here things end, or so we hope...
if (m{^\s*\*/}) {
# not copyright means fixup of the saved comment block...
if ($comment[1] !~ m/Copyright/) {
$comment[0] =~ s{/\*\*}{/*!};
if (@comment > 2) {
for my $i (1..$#comment-1) {
$comment[$i] =~ s{^(\s*)\*(\s)}{$1 $2};
}
}
}
# emit and reset
print for @comment;
@comment = ();
}
next LINE;
}
# hopefully only not-comment lines
print;
}
답변2
주석 블록이 줄의 시작 부분에 있다고 가정하면(앞에 공백이 없음 /**
) 다음과 같이 작동할 수 있습니다.
#!/usr/bin/awk -f
/^\/[*][*] Copyright/ {print; next} # 1
/^\/[*][*]/ { flag = 1; sub("^/[*][*] ", "/*! ") } # 2
flag && /^ \* / { sub("^ [*]", " ") } # 3
/ [*]\// { flag = 0 } 1; # 4
(1) 가 있으면 /** Copyright
인쇄하고 다음 줄로 이동합니다. (2) 다른 것이 있으면 /**
주석 블록에 있음을 표시하는 플래그를 설정하고 로 바꾸십시오 /*!
. (3) 해당 플래그가 설정되어 있으면 줄 시작 부분에서 별표를 제거하십시오. (4) 주석이 끝나면( */
a 가 표시됨) 플래그가 지워지고 1
끝의 줄이 인쇄됩니다.
시험:
$ cat comments
/** foo
* bar
*/
* This isn't a comment
/** Copyright
* isn't changed
*/
$ awk -f strip.awk comments
/*! foo
bar
*/
* This isn't a comment
/** Copyright
* isn't changed
*/