【问题标题】:Perl regular expression to split string by wordPerl正则表达式逐字分割字符串
【发布时间】:2017-12-19 12:58:41
【问题描述】:

我有一个由几个单词组成的字符串(用大写字母分隔)。

例如:

$string1="TestWater"; # to be splited in an array @string1=("Test","Water")
$string2="TodayIsNiceDay"; # as @string2=("Today","Is","Nice","Day")
$string3="EODIsAlwaysGood"; # as @string3=("EOD","Is","Always","Good")

我知道 Perl 很容易拆分使用拆分功能来固定字符,或者匹配正则表达式可以将 $1、$2 与固定数量的变量分开。但是如何动态地做到这一点呢?提前致谢!

Spliting CamelCase 的帖子没有回答我的问题,我的问题与 Perl 中的正则表达式更相关,即 Java 中的正则表达式(此处存在差异)。

【问题讨论】:

标签: regex perl


【解决方案1】:

您可以通过在列表上下文中使用m//g 来执行此操作,它会返回找到的所有匹配项的列表。 (经验法则:如果您知道要提取什么,请使用m//g;如果您知道要丢弃什么,请使用split。)

您的情况有点复杂,因为您想将"EODIs" 拆分为("EOD", "Is")

以下代码处理这种情况:

my @words = $string =~ /\p{Lu}(?:\p{Lu}+(?!\p{Ll})|\p{Ll}*)/g;

即每个单词都以大写字母 (\p{Lu}) 开头,后跟任一

  • 1 个或多个大写字母(但最后一个字母后面没有小写字母),或
  • 0 个或多个小写字母 (\p{Ll})

【讨论】:

  • 我真的很喜欢你的回答,非常简洁。非常感谢!
【解决方案2】:

使用split 在正则表达式上拆分字符串。你要的是一个大写字符后面不跟一个大写字符作为边界,可以用两个前瞻断言来表示(详情perlre):

#!/usr/bin/perl
use warnings;
use strict;

use Test::More;

sub split_on_capital {
    my ($string) = @_;
    return [ split /(?=[[:upper:]](?![[:upper:]]))/, $string ]
}

is_deeply split_on_capital('TestWater'),       [ 'Test', 'Water' ];
is_deeply split_on_capital('TodayIsNiceDay'),  [ 'Today', 'Is', 'Nice', 'Day' ];
is_deeply split_on_capital('EODIsAlwaysGood'), [ 'EOD', 'Is', 'Always', 'Good' ];

done_testing();

【讨论】:

  • 为什么不会为TestWaterTodayIsNiceDay 生成空的前导元素?
  • @melpomene:记录在split:EXPR 开头的零宽度匹配永远不会产生空字段
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-06
  • 1970-01-01
  • 1970-01-01
  • 2013-05-20
  • 2017-09-05
  • 2011-12-22
  • 1970-01-01
相关资源
最近更新 更多