Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 帮助转换为子例程_Perl - Fatal编程技术网

Perl 帮助转换为子例程

Perl 帮助转换为子例程,perl,Perl,我试图将我的代码转换成一系列子例程,使其更加模块化。下面代码中的条件语句是我无法合并到子例程中的 next unless ( $sentblock =~ /\[sent. \d+ len. \d+\]: \[.+\]/ ); #1# ( $sentence, $sentencenumber ) = &sentence_sentnum_chptnum($sentblock); #SUBROUTINE if ( $sentence =~ /\~\s(\d*F*[\

我试图将我的代码转换成一系列子例程,使其更加模块化。下面代码中的条件语句是我无法合并到子例程中的

next unless ( $sentblock =~ /\[sent. \d+ len. \d+\]: \[.+\]/ );               #1#
( $sentence, $sentencenumber ) = &sentence_sentnum_chptnum($sentblock); #SUBROUTINE
if ( $sentence =~ /\~\s(\d*F*[\.I_]\w+)\s/ ) {                                #2#
    $chapternumber = $1;
    $chapternumber =~ tr/./_/;
}
next
  unless ( $sentence =~ /\b\Q$search_key\E/i                                  #3#
    && $sentence =~ /\b\Q$addkey0\E/i
    && $sentence =~ /\b\Q$addkey1\E/i );
next
  if ( defined($exc0)                                                         #4#
    && length($exc0)
    && $sentence =~ /\b\Q$exc0\E\b/i );
next
  if ( defined($exc1)                                                         #5#
    && length($exc1)
    && $sentence =~ /\b\Q$exc1\E\b/i );
到目前为止,子例程:

sub sentence_sentnum_chptnum {
    my $subsentblock = shift;
    my ( $subsentence, $subsentencenumber );
    return unless ( $subsentblock =~ /\[sent. (\d+) len. \d+\]: \[(.+)\]/ ); #DIDN'T replace the need to put one in the main script
    $subsentencenumber = $1;
    $subsentence       = $2;
    $subsentence =~ s/, / /g;
    return ( $subsentence, $subsentencenumber );
}
它按原样工作,但如果我尝试将其他条件语句放入:我会在代码的后面出现错误,说
$句子未初始化。示例:如果我尝试使用相同的条件包含对
$addkey
的检查,但只是将
next
替换为
return
我会在以下行中得到一个错误:
If($句子=~/\~\s(\d*F*[\.I]\w+\s/){
同样,如果我将这些条件中的任何一个放入子例程中

next unless ( $sentblock =~ /\[sent. \d+ len. \d+\]: \[.+\]/ );               #1#
( $sentence, $sentencenumber ) = &sentence_sentnum_chptnum($sentblock); #SUBROUTINE
if ( $sentence =~ /\~\s(\d*F*[\.I_]\w+)\s/ ) {                                #2#
    $chapternumber = $1;
    $chapternumber =~ tr/./_/;
}
next
  unless ( $sentence =~ /\b\Q$search_key\E/i                                  #3#
    && $sentence =~ /\b\Q$addkey0\E/i
    && $sentence =~ /\b\Q$addkey1\E/i );
next
  if ( defined($exc0)                                                         #4#
    && length($exc0)
    && $sentence =~ /\b\Q$exc0\E\b/i );
next
  if ( defined($exc1)                                                         #5#
    && length($exc1)
    && $sentence =~ /\b\Q$exc1\E\b/i );
主要问题:我如何才能:

(1) 除非($sentblock=~/\[sent.\d+len.\d+\]:\[.+\]/);
(它也在子例程中)

(2) 包括:
if($句子=~/\~\s(\d*F*[\.I\u]\w+\s/)
&所有3个
下一个
语句

(3) 由于它已包含在内,因此也返回
$chapternumber

不影响我的代码

一般最佳实践问题:如果我在代码顶部定义了变量(来自HTML表单),那么每次在每个子例程中对它们进行本地化是更好的做法,还是不将任何内容传递到子例程中,并使用在代码开头指定的值?(例如
$search\u key
$addkey
$exc

测试用例我制作了一个测试用例,但是它很长,所以我没有包含它。如果您需要,它非常类似于:只需找到子例程接管的位置并删除该部分……它就在我的$sentblock(@parsed)后面

注意:测试用例不包括
addkey
exc
,并且没有任何内容与章节号匹配(在一个句子前面加上“~5.5”以包含它)

我已尝试在主程序中检查返回的
$语句。这消除了错误,但程序的其余部分没有匹配项(即搜索引擎的最终结果为0个结果)

谢谢,如果有任何不清楚的地方,请告诉我。

尝试这种方法(您可能对其中一些代码很熟悉;-):

然后,将您的第一个列表替换为

($sentence, $sentenceNumber, $chapterNumber) = extractSentenceAndPositions($sentblock);
next if (!$sentence || !$sentenceNumber || !$chapterNumber);
关于您的最佳实践问题,我想说对于这个用例(cgi变量等),这些值几乎肯定不会改变,我会直接引用它们。我通常遵循的基本概念是在运行开始时擦洗它们一次(我的意思是清理掉SQL注入、XSS、XSRF、shell注入或值中的其他此类肮脏内容)并从那时起将它们视为只读全局变量。我在这个问题上听到了其他观点,但我通常都是这样做的


至于检查主程序中返回的
$语句
是否以某种方式破坏了所有其他匹配项,我不确定这将如何发生,除非发生其他情况。我使用了这种方法(
next
last
,基于返回值)在众多的脚本中,并没有什么内在的破坏性。

您希望分解多少东西?如果没有更多的代码,很难看出分解东西的“最佳”或“正确”方式是什么

一般来说,如果您浏览代码并添加注释来描述每个代码块的功能,那么您也可以用一个子块替换每个注释块,该子块的名称可以重述以下句子:

# Is this a sentence block?
next unless ( $sent_block =~ /\[sent. \d+ len. \d+\]: \[.+\]/ );    
           #1#

my ( $sentence, $sentence_number ) = parse_sentence_block($sent_block);

# Get chapter info if present
if ( $sentence =~ /\~\s(\d*F*[\.I_]\w+)\s/ ) {                                #2#
    $chapter_number = $1;
    $chapter_number =~ tr/./_/;
}

# Skip if key found
next
  unless ( $sentence =~ /\b\Q$search_key\E/i                                  #3#
    && $sentence =~ /\b\Q$addkey0\E/i
    && $sentence =~ /\b\Q$addkey1\E/i );

# skip if excrescence 0 (or whatever exc is short for)
next
  if ( defined($exc0)                                                         #4#
    && length($exc0)
    && $sentence =~ /\b\Q$exc0\E\b/i );
# skip if excrescence 1.
next
  if ( defined($exc1)                                                         #5#
    && length($exc1)
    && $sentence =~ /\b\Q$exc1\E\b/i );
现在,将这些评论编入subs:

next unless is_sentence_block( $sent_block );

my( $sentence, $sentence_number ) = parse_sentence_block($sent_block);

# Maybe update the chapter number
my $new_chapter_number = get_chapter_number( $sentence );
$chapter_number = $new_chapter_number if defined $new_chapter_number;

next unless have_all_keys( $sentence => $search_key, $add_key0, $add_key1 ); 

next if have_excrescence( $exc0 );
next if have_excrescence( $exc1 );


sub is_sentence_block {
    my $block = shift;

    return $sent_block =~ /\[sent. \d+ len. \d+\]: \[.+\]/ );
}

sub get_chapter_number {
    my $sentence = shift;

    return unless $sentence =~ /\~\s(\d*F*[\.I_]\w+)\s/;
    return $1;
}

sub have_all_keys {
     my $sentence = shift;
     my @keys = @_;

     for my $key ( @keys ) { 
         return unless $sentence =~ /\b\Q$key1\E/i;
     }

     return 1
}

sub have_excrescence {
    my $sentence = shift;
    my $exc      = shift;

    return 0 unless defined($exc);
    return 0 unless length($exc)
    return 0 unless $sentence =~ /\b\Q$exc\E\b/i );

    return 1;
}

我不会有多大帮助,因为我现在只限于我的iPhone,但对于我所见过的一个问得最多的问题来说+1。我很困惑,这看起来是可行的,但是当我这样做时,它返回0个匹配项(即,如果我省略
下一个if(!$sen…)
它输出为空,计数为1个匹配项).因此,不知何故,这个句子没有被传递。我通常会责怪我的正则表达式或算法,但当它在子例程之外时,它就会工作!!这是我通常进入调试领域的时间。
print
s适用于所有人!:-)说真的,在调用之前和之后进行
print
打印对初学者来说可能不是个坏主意。在子调用之前和之后所有
$sent*
变量的内容是什么?更进一步,在子调用中喷洒
print
s以查看它所点击的代码路径也是有价值的。对不起,如果没有示例数据和/或更多的代码上下文,可能会发生很多事情。我可以做很多猜测,但我不知道其中任何一个会是明智的。:-)逻辑的巨大负载让我们感到害怕。要理解它,我需要一个真值表。有效的批评。我通常避免这些事情。我做到了这里只是因为它是(和等价物)的直接翻译接下来是原始的
,除非注释中提到了
链。Ie-我觉得这可能会使从主体代码到子例程代码的转换更加清晰。非常感谢,我一定会尝试通过一些打印和“调试区”找到漏洞所在。不过,在那之前,我只接受分解版本好吧,一些好消息:这是可行的。所以通过测试每个返回,它的工作原理是相同的。我还没有能够制作一个子例程来封装所有这些子例程,但我认为这已经足够好了。