Làm cách nào để in regex mở rộng ở dạng chưa được mở rộng?


8

Có thể in biểu thức chính được tạo bằng ký hiệu mở rộng ( qr/.../x) ở dạng không mở rộng không? Ví dụ:

my $decimal = qr/
  (?=\d|\.\d)  # look-ahead to ensure at least one of the optional parts matches
  \d*          # optional whole digits
  (?:\.\d*)?   # optional decimal point and fractional digits
/x;

say $decimal;

Tôi muốn điều này được in như (?=\d|\.\d)\d*(?:\.\d*)?.

Tôi có thể viết một trình phân tích cú pháp để loại bỏ các phần không có chức năng nhưng điều đó sẽ sao chép những gì perl đã làm và tôi có thể gặp một số trường hợp không tầm thường.

(Vâng, điều này có vẻ hơi ngớ ngẩn. Tôi có một trường hợp sử dụng mà tôi cần in rất nhiều tin nhắn như matched <pattern>và tôi muốn giới hạn tin nhắn trong một dòng trong khi cho phép sử dụng ký hiệu mở rộng cho các mẫu.)


Bình luận không dành cho thảo luận mở rộng; cuộc trò chuyện này đã được chuyển sang trò chuyện .
Samuel Liew

Câu trả lời:


7

Perl không cung cấp một tiện ích như vậy. Nó phân tích các mẫu regex; nó không tạo ra chúng. Việc xâu chuỗi của đối tượng là chuỗi chính xác được cung cấp cho trình phân tích cú pháp, được gói trong một (?:...)tài khoản cho các cờ. Chuỗi được cung cấp cho trình phân tích cú pháp là chuỗi ký tự sau nội suy trừ các dấu phân cách. [1]

Điều đó nói rằng, điều này sẽ không quan trọng để làm với trình phân tích cú pháp regex.

YAPE :: Regex , nhưng nó đã không được cập nhật trong một thời gian dài. Ví dụ, nó không hỗ trợ (?^:...)tìm thấy trong chuỗi chuỗi regex trong phiên bản hiện đại của Perl.

Ngoài ra còn có Regapi :: Parser . Nó mới hơn, nhưng nó cũng không hỗ trợ (?^:...)! Nhưng nếu chúng ta giải quyết vấn đề đó, nó sẽ thật hoàn hảo vì tự nhiên bỏ qua khoảng trắng và bình luận! Tất cả những gì chúng ta cần làm là phân tích mô hình và nhận được một chuỗi nghiêm ngặt từ cây phân tích cú pháp.

Cuối cùng, có Regapi :: Parsertron . Đây là phiên bản mới nhất và nó hỗ trợ (?^:...), nhưng nó không phân biệt khoảng trắng và nhận xét với mã thông báo "khớp chính xác".

Vì vậy, hãy sử dụng Regapi :: Parser. [2]

#!/usr/bin/perl
use strict;
use warnings;
use feature qw( say );

use Regexp::Parser qw( );

{
   @ARGV == 1
      or die("usage\n");

   my $re = $ARGV[0];

   # R::P doesn't support «(?^:...)», so we'll
   # provide a backwards-compatible stringification.
   $re =~ s{^\(\?\^(\w*):}{
      my %on = map { $_ => 1 } split //, $1;
      my $on  = join "", grep  $on{$_}, qw( i m s x );
      my $off = join "", grep !$on{$_}, qw( i m s x );
      "(?$on-$off:"
   }e;

   my $parser = Regexp::Parser->new($re);
   my $roots = $parser->root
      or die($parser->errmsg);

   say join "", map $_->visual, @$roots;
}

Kiểm tra:

$ despace_re '(?^x:
   (?=\d|\.\d)  # look-ahead to ensure at least one of the optional parts matches
   \d*          # optional whole digits
   (?:\.\d*)?   # optional decimal point and fractional digits
)'
(?x-ims:(?=\d|\.\d)\d*(?:\.\d*)?)

  1. \Q, \uVà tương tự được thực hiện tại cùng một sân khấu tại nội suy. \N{...}được giải quyết để \N{U+...}bất tử các cài đặt tên hiện tại. Thoát khác như \x27, \x{0000027}, \\\/được bảo quản nhân vật cho nhân vật.

  2. Một giải pháp dựa trên YAPE :: Regex đã được sử dụng trong phiên bản trước của câu trả lời này.


1
Thêm tìm thấy của bạn với re::regex_pattern($qr)? Điều đó cho họ một cách để có được những gì họ cần, hoặc gần với điều đó, có lẽ với một phụ đơn giản
zdim

@zdim, tôi không thấy re::regex_pattern($qr)giúp được gì cả.
ikegami

Nó loại bỏ những thứ xung quanh ( (?: )) ... đó là điều gì đó '. Các không gian chông gai tôi nhận ra - nếu có xmod vẫn có thể có không gian pháp lý bên trong [ ](một ví dụ tôi có thể nhớ lại, có lẽ còn nhiều hơn nữa) ... nhưng chúng có thể loại bỏ các dòng mới bằng tay không? Sau đó, có một bản in chấp nhận được?
zdim

@zdim, nhưng loại bỏ những thứ đó là một điều xấu. Nó có thể thay đổi mô hình có nghĩa là một cái gì đó khác. Nó ở đó bởi vì nó là một phần quan trọng của mô hình.
ikegami

@zdim, Bốn trường hợp khoảng trắng là đáng kể khi sử dụng /x: \␠, [␠], (?-x:␠)(?-x)␠. Có thể có nhiều hơn.
ikegami
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.