2009-05-18 27 views
5

Bất cứ ai có thể làm cho tôi với các biểu thức chính quy để loại bỏ ý kiến ​​nhiều dòng và bình luận dòng đơn trong một tập tin?Làm thế nào tôi có thể loại bỏ các ý kiến ​​C đa dòng từ một tệp bằng Perl?

ví dụ:

    " WHOLE "/*...*/" HAS TO BE STRIPED OFF....." 

1. /* comment */ 
2. /* comment1 */ code /* comment2 */ #both /*comment1*/ and /*comment2*/ 
              #has to striped off and rest should 
               #remain. 
3. /*......... 
     ......... 
     ......... 
     ......... */ 

tôi thực sự đánh giá cao bạn nếu u làm nhu cầu này .... cảm ơn trước.

+1

Theo quy tắc chung, tôi thấy rằng khi bạn đang cố gắng thao tác một ngôn ngữ lập trình như C, XML, SQL, v.v ... bạn thực sự nên nghĩ đến một trình phân tích cú pháp chứ không phải regex. Tôi rất khuyên bạn nên tìm hiểu về máy phát điện phân tích cú pháp, yacc, javacc, v.v. Nó đã có những phần thưởng lớn đối với tôi như một nhà phát triển phần mềm. – zimbu668

Trả lời

-2

kiểm tra bao gồm:

use strict; 
use warnings; 
use Test::More qw(no_plan); 
sub strip_comments { 
    my $string=shift; 
    $string =~ s#/\*.*?\*/##sg; #strip multiline C comments 
    return $string; 
} 
is(strip_comments('a/* comment1 */ code /* comment2 */b'),'a code b'); 
is(strip_comments('a/* comment1 /* comment2 */b'),'ab'); 
is(strip_comments("a/* comment1\n\ncomment */ code /* comment2 */b"),'a code b'); 
+0

tuyệt vời .... cảm ơn rất nhiều – User1611

+3

Sẽ mess up/* hoặc */xuất hiện trong một chuỗi. Ví dụ. chuỗi "This/* string" không bao gồm bắt đầu nhận xét. – Richard

+2

Cũng như không xử lý các ký tự bình luận trong chuỗi (hoặc thậm chí các hằng số ký tự nhiều ký tự), nó cũng không xử lý các dấu gạch chéo ngược dòng mới cho phép dấu gạch chéo mở được theo sau bởi dấu gạch chéo ngược, dòng mới và sau đó là dấu hoa thị. Cũng không xử lý các chú thích C++ (cũng có thể có nối tiếp dòng ngược dòng). Và nó không xử lý các dấu vết - cái duy nhất có liên quan là '?? /' có nghĩa là dấu gạch chéo ngược. Vấn đề này phụ thuộc vào cách mã của bạn cần phải được mã hóa. –

11

Như thường lệ trong Perl, bạn có thể liên hệ với CPAN: Regexp::Common::Comment sẽ giúp bạn. Một ngôn ngữ tôi tìm thấy sử dụng các chú thích bạn mô tả là Nickle, nhưng có lẽ các chú thích PHP sẽ là OK (// cũng có thể bắt đầu một chú thích một dòng).

Lưu ý rằng trong mọi trường hợp, sử dụng regexps để loại bỏ nhận xét là nguy hiểm, trình phân tích cú pháp đầy đủ cho ngôn ngữ ít rủi ro hơn nhiều. Ví dụ: trình phân tích cú pháp regexp có thể bị nhầm lẫn bởi một cái gì đó như print "/*";.

0

Remove/* */ý kiến ​​(bao gồm nhiều dòng)

s/\/\*.*?\*\///gs 

tôi đăng bài này vì nó rất đơn giản, tuy nhiên tôi tin rằng nó sẽ đi lên trên nhúng nhận xét như

/* sdafsdfsdf /*sda asd*/ asdsdf */ 

Nhưng vì chúng khá phổ biến, tôi thích regex đơn giản hơn.

+0

tuyệt vời ... hoạt động tốt ... cảm ơn rất nhiều .. – User1611

+0

tuyệt vời .. cảm ơn u ... – User1611

+1

Đọc câu trả lời của tôi để xem tại sao điều này là sai. –

6

Đây là một câu hỏi thường gặp:

perldoc -q comment 

Tìm thấy trong perlfaq6:

Làm thế nào để sử dụng một biểu thức chính quy để dải comments C phong cách từ một tập tin?

Trong khi điều này thực sự có thể được thực hiện, nó khó hơn bạn nghĩ nhiều. Đối với dụ, điều này một liner ...

+0

Bạn có thể liên kết đến perlfaqs tại http://faq.perl.org (luôn là phiên bản mới nhất) hoặc perldoc.perl.org. Bằng cách đó, các trang web đó có được nước ép tốt cho những người tìm kiếm câu trả lời. :) –

16

Từ perlfaq6 "Làm thế nào để sử dụng một biểu thức chính quy để dải comments C phong cách từ một tập tin?":


Trong khi điều này thực sự có thể được thực hiện, nó khó hơn nhiều so với bạn nghĩ. Ví dụ: một lớp lót này

perl -0777 -pe 's{/\*.*?\*/}{}gs' foo.c 

sẽ hoạt động trong nhiều trường hợp nhưng không phải tất cả các trường hợp. Bạn thấy đấy, nó quá đơn giản, có đầu óc đối với một số loại chương trình C, đặc biệt là những chương trình có vẻ như là những nhận xét trong các chuỗi được trích dẫn. Vì điều đó, bạn cần một cái gì đó như thế này, được tạo ra bởi Jeffrey Friedl và sau đó được sửa đổi bởi Fred Curtis.

$/ = undef; 
$_ = <>; 
s#/\*[^*]*\*+([^/*][^*]*\*+)*/|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)#defined $2 ? $2 : ""#gse; 
print; 

Tất nhiên, điều này có thể được viết rõ ràng hơn với bộ sửa đổi/x, thêm khoảng trắng và nhận xét. Ở đây nó được mở rộng, lịch sự của Fred Curtis.

s{ 
    /\*   ## Start of /* ... */ comment 
    [^*]*\*+ ## Non-* followed by 1-or-more *'s 
    (
    [^/*][^*]*\*+ 
    )*   ## 0-or-more things which don't start with/
       ## but do end with '*' 
/   ## End of /* ... */ comment 

|   ##  OR various things which aren't comments: 

    (
    "   ## Start of " ... " string 
    (
     \\.   ## Escaped char 
    |    ## OR 
     [^"\\]  ## Non "\ 
    )* 
    "   ## End of " ... " string 

    |   ##  OR 

    '   ## Start of ' ... ' string 
    (
     \\.   ## Escaped char 
    |    ## OR 
     [^'\\]  ## Non '\ 
    )* 
    '   ## End of ' ... ' string 

    |   ##  OR 

    .   ## Anything other char 
    [^/"'\\]* ## Chars which doesn't start a comment, string or escape 
    ) 
}{defined $2 ? $2 : ""}gxse; 

Một sửa đổi chút ít cũng loại bỏ C++ bình luận, có thể kéo dài nhiều dòng sử dụng một nhân vật tiếp tục:

s#/\*[^*]*\*+([^/*][^*]*\*+)*/|//([^\\]|[^\n][\n]?)*?\n|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)#defined $3 ? $3 : ""#gse; 
+0

brian, chức năng đó gần như có thể được thêm vào perl, nó dường như được hỏi rất nhiều. ít nhất là IMO. –

+0

... và đây là lý do tại sao chúng tôi có các công cụ như yacc, flex, bison, ANTLR, v.v. Đây là thứ bạn cần một trình phân tích cú pháp toàn diện, không phải là regex. –

+2

@Paul: Chức năng đó đã có trong Perl. Perl là một ngôn ngữ mục đích chung. Chúng tôi không muốn thêm các tính năng tích hợp cho mọi tác vụ đi kèm. Đó là công việc cho các mô-đun. –

1

Ngoài ra còn có một câu trả lời không perl: sử dụng chương trình stripcmt:

StripCmt là một tiện ích đơn giản được viết trong C để xóa nhận xét từ C, C++, và các tệp nguồn Java. Trong số truyền thống lớn về xử lý văn bản Unix chương trình, nó có thể hoạt động như bộ lọc FIFO (First In - First Out) hoặc chấp nhận đối số trên dòng lệnh.

Các vấn đề liên quan