【问题标题】:Perl Pattern Matching QuestionPerl 模式匹配问题
【发布时间】:2010-12-01 23:26:56
【问题描述】:

我正在尝试匹配 perl 中的模式,需要一些帮助。

我需要从字符串中删除任何与 [xxxx] 匹配的内容,即打开括号-其中的内容-出现的第一个右括号。

所以我试图用空格替换左括号,里面的东西,第一个右括号,代码如下:

   if($_ =~ /[/)
  {
    print "In here!\n";
    $_ =~ s/[(.*?)]/ /ig;
  }

同样,我需要匹配,即尖括号-里面的东西-第一个闭合尖括号。

我正在使用以下代码:

   if($_ =~ /</)
  {
    print "In here!\n";
    $_ =~ s/<(.*?)>/ /ig;
  }

这似乎不起作用。我的示例数据如下:

 'Joanne' <!--Her name does NOT contain "Kathleen"; see the section "Name"--> "'Jo'" 'Rowling', OBE [http://news bbc co uk/1/hi/uk/793844 stm Caine heads birthday honours list]  BBC News  17 June 2000  Retrieved 25 October 2000  , [http://content scholastic com/browse/contributor jsp?id=3578 JK Rowling Biography]  Scholastic com  Retrieved 20 October 2007  better known as 'J  K  Rowling' ,<ref name=telegraph>[http://www telegraph co uk/news/uknews/1531779/BBCs-secret-guide-to-avoid-tripping-over-your-tongue html Daily Telegraph, BBC's secret guide to avoid tripping over your tongue, 19 October 2006] is a British <!--do not change to "English" or "Scottish" until issue is resolved --> author best known as the creator of the [[Harry Potter]] fantasy series, the idea for which was conceived whilst on a train trip from Manchester to London in 1990  The Potter books have gained worldwide attention, won multiple awards, sold more than 400 million copies and been the basis for a popular series of films, in which Rowling had creative control serving as a producer in two of the seven installments  [http://www businesswire com/news/home/20100920005538/en/Warner-Bros -Pictures-Worldwide-Satellite-Trailer-Debut%C2%A0Harry Business Wire - Warner Bros  Pictures mentions J  K  Rowling as producer ] 

任何帮助将不胜感激。谢谢!

【问题讨论】:

    标签: regex perl pattern-matching


    【解决方案1】:

    你需要使用这个:

    1 while s/\[[^\[\]]*\];
    

    演示:

    % echo "i have [some [square] brackets] in [here] and [here] today."| perl -pe '1 while s/\[[^\[\]]*\]/NADA/g'
    i have NADA in NADA and NADA today.
    

    相对于失败:

    % echo "i have [some [square] brackets] in [here] and [here] today." | perl -pe 's/\[.*?\]/NADA/g'
    i have NADA brackets] in NADA and NADA today.
    

    我留给读者作为练习的递归正则表达式。 :)


    编辑: Eric Strom 提供了一个递归解决方案,您不必使用 1 while

    % echo "i have [some [square] brackets] in [here] and [here] today." | perl -pe 's/\[(?:[^\[\]]*|(?R))*\]/NADA/g'
    i have NADA in NADA and NADA today.
    

    【讨论】:

    • s/\\[(?:[^\\[\\]]*|(?R))*\\]/NADA/g
    【解决方案2】:

    $_ =~ /someregex/ 不会修改$_

    请注意,$_ =~ /someregex//someregex/ 做同样的事情。

    另外,您不需要检查 [ 或

    s/\[.*?\]/ /g;

    s/<.>/ /g;

    会做你想做的工作。

    编辑:更改代码以匹配您正在修改 $_ 的事实

    【讨论】:

    • 我很困惑。你说的这些替换中的哪一个有什么作用?
    • 请注意 ?很重要。它告诉 Perl 不要进行贪心匹配。否则,您将匹配“[asfs [safs] asfsd]”
    • @tchrist 他的原始代码试图同时删除 [...] 和 <...>。第 1 行删除 [...],第 2 行删除 <...>。
    • @mmccoo 当前代码将匹配您示例中的“[asfs [safs]”,留下“asfsd]”。这可能是不希望的,但示例数据中未包含该构造。
    【解决方案3】:
    • 方括号在正则表达式语法中具有特殊含义,因此请转义它们:/\[.*?\]/。 (这里也不需要括号,做不区分大小写的匹配是没有意义的。)

    • 自从我不得不与 Perl 搏斗已经很久了,但我很确定用正则表达式测试 $_ 也会修改 $_(即使你没有使用 s///) .无论如何,您都不需要测试;只需运行替换,如果模式在任何地方都不匹配,那么它不会做任何事情。

    【讨论】:

    • 模式匹配操作不会修改匹配的字符串。如果是这样,您将无法匹配常量,但您可以:"REPORT" =~ /^\Q$choice/i
    • 我没想到它会修改字符串 per se,而是在 $_ 上报告成功或失败,从而覆盖为匹配而提供的 $_。
    • m// 运算符从不写信给$_。它将在标量上下文中返回 true 或 false,在列表上下文中返回匹配的组。数字匹配变量$1, $2, $3 ... 将设置为相应的匹配组。
    • 谢谢;我知道有一个我不完全确定的原因。 :)
    猜你喜欢
    • 2011-06-04
    • 2016-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-17
    • 2020-07-05
    • 1970-01-01
    相关资源
    最近更新 更多