Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.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
Regex 拆分所有单词,但保留拆分的字符_Regex_Perl - Fatal编程技术网

Regex 拆分所有单词,但保留拆分的字符

Regex 拆分所有单词,但保留拆分的字符,regex,perl,Regex,Perl,在Perl中,我试图从一段文本构建一个包含所有单词的数组 现在我正在使用@tokens=split/[^\w']+/,$mytext 它似乎得到了所有的alphanum单词,但我希望所有的标点符号都被认为是一个单词,除了下划线。范例 你好。我的名字是first\u last… 应该变成:嗨,我的名字是,第一个,最后一个 总共9个单词 我该怎么做?我试着在标点符号上拆分,但没有保存标点符号。一种方法是:你想在空格上拆分(1);(2) 只要上一个字符位于[^\w']中(字符串末尾除外);和(3)每当

在Perl中,我试图从一段文本构建一个包含所有单词的数组

现在我正在使用
@tokens=split/[^\w']+/,$mytext

它似乎得到了所有的alphanum单词,但我希望所有的标点符号都被认为是一个单词,除了下划线。范例

你好。我的名字是first\u last…

应该变成:嗨,我的名字是,第一个,最后一个

总共9个单词

我该怎么做?我试着在标点符号上拆分,但没有保存标点符号。

一种方法是:你想在空格上拆分(1);(2) 只要上一个字符位于
[^\w']
中(字符串末尾除外);和(3)每当下一个字符在
[^\w']
中时(字符串开头除外),您可以编写:

@tokens = split /\s+|(?<=[^\w'])|(?=(?!^)[^\w'])/, $mytext;
@tokens=split/\s+|(?一种方法是使用:您希望拆分(1)空格;(2)上一个字符在
[^\w']
中时(字符串末尾除外);以及(3)下一个字符在
[^\w']
中时(字符串开头除外),以便您可以编写:

@tokens = split /\s+|(?<=[^\w'])|(?=(?!^)[^\w'])/, $mytext;

@tokens=split/\s+|(?通常比split更容易匹配;听起来像是要匹配任何一系列单引号/单词字符(包括)或任何其他非空白字符:

my $mytext = 'hi. my name is first_last ...';
my @tokens = $mytext =~ /([\w']+|\S)/g;
print join( ' , ',  @tokens ),"\n";
产生:

hi , . , my , name , is , first_last , . , . , .

[\w']
是一个字符类,允许使用任何单词字符(字母、数字或下划线)或单引号;可以添加其他字符,但有些字符可能需要转义(例如
[\w'\-]
以添加连字符).

匹配通常比拆分更容易;听起来像是要匹配任何一系列单引号/单词字符(包括_)或任何其他非空白字符:

my $mytext = 'hi. my name is first_last ...';
my @tokens = $mytext =~ /([\w']+|\S)/g;
print join( ' , ',  @tokens ),"\n";
产生:

hi , . , my , name , is , first_last , . , . , .
[\w']
是一个字符类,允许使用任何单词字符(字母、数字或下划线)或单引号;可以添加其他字符,但有些字符可能需要转义(例如
[\w'\-]
以添加连字符)

增加:

代码:

my $inp   = 'hi. my name is first_last ...';
my @parts = split /(\W)/, $inp;
printf "%d parts: (%s)\n", scalar @parts, join('), (', @parts);
@parts = grep {$_ gt ' '} @parts;
printf "%d parts: (%s)\n", scalar @parts, join('), (', @parts);
输出:

18 parts: (hi), (.), (), ( ), (my), ( ), (name), ( ), (is), ( ), (first_last), ( ), (), (.), (), (.), (), (.)
9 parts: (hi), (.), (my), (name), (is), (first_last), (.), (.), (.)
增加:

代码:

my $inp   = 'hi. my name is first_last ...';
my @parts = split /(\W)/, $inp;
printf "%d parts: (%s)\n", scalar @parts, join('), (', @parts);
@parts = grep {$_ gt ' '} @parts;
printf "%d parts: (%s)\n", scalar @parts, join('), (', @parts);
输出:

18 parts: (hi), (.), (), ( ), (my), ( ), (name), ( ), (is), ( ), (first_last), ( ), (), (.), (), (.), (), (.)
9 parts: (hi), (.), (my), (name), (is), (first_last), (.), (.), (.)

如果这是你的话

hi. my name is first_last ...
11  22 3333 44 5555555555
这些不是你的分离器

hi. my name is first_last ...
  11  22   33 4          5555
那么您实际上并不是在拆分单词(而且
split
可能不会很好地工作)。您实际上需要一个标记器

以下是构建令牌服务器的一般方法:

my @tokens;
for ($mytext) {
   /\G \s+ /xgc;
   if (/\G ( [\w']+   ) /xgc) { push @tokens, $1; redo; }
   if (/\G ( [^\s\w'] ) /xgc) { push @tokens, $1; redo; }
   die "Bad code";
}
但我们可以简化这一点

my @tokens = $mytext =~ /\G\s*([\w']+|[^\S\w'])/g;
甚至

my @tokens = $mytext =~ /\G\s*([\w']+|\S)/g;

如果这是你的话

hi. my name is first_last ...
11  22 3333 44 5555555555
这些不是你的分离器

hi. my name is first_last ...
  11  22   33 4          5555
那么您实际上并不是在拆分单词(而且
split
可能不会很好地工作)。您实际上需要一个标记器

以下是构建令牌服务器的一般方法:

my @tokens;
for ($mytext) {
   /\G \s+ /xgc;
   if (/\G ( [\w']+   ) /xgc) { push @tokens, $1; redo; }
   if (/\G ( [^\s\w'] ) /xgc) { push @tokens, $1; redo; }
   die "Bad code";
}
但我们可以简化这一点

my @tokens = $mytext =~ /\G\s*([\w']+|[^\S\w'])/g;
甚至

my @tokens = $mytext =~ /\G\s*([\w']+|\S)/g;

扩展ysth的想法:

my $mytext = 'hi. My name22222 is first_last!? 2,0 #@/';
my @tokens = $mytext =~ /([a-zA-Z_]+|[0-9]+|[.?!,])/g;
print join ":", @tokens,"\n";
输出:

hi:.:My:name:22222:is:first_last:!:?:2:,:0:
这更容易理解,因为它避免了使用\w和\S。\w包含的内容比您想象的要多,因为它包含了u,这很容易混淆。\S也不仅仅匹配标点符号


上面展示了如何使用|拆分组成一个单词的字符集,并明确定义字符。不属于任何单词的“垃圾”将被过滤掉。

扩展ysth的思想:

my $mytext = 'hi. My name22222 is first_last!? 2,0 #@/';
my @tokens = $mytext =~ /([a-zA-Z_]+|[0-9]+|[.?!,])/g;
print join ":", @tokens,"\n";
输出:

hi:.:My:name:22222:is:first_last:!:?:2:,:0:
这更容易理解,因为它避免了使用\w和\S。\w包含的内容比您想象的要多,因为它包含了u,这很容易混淆。\S也不仅仅匹配标点符号


上面展示了如何使用|拆分组成一个单词的字符集,并显式定义这些字符。“垃圾”这不是任何单词的一部分被过滤掉。

这部分的哪一部分允许uuu出现在单词中?如果我想在单词中允许另一个字符,如连字符,该怎么办?这部分的哪一部分允许uuu出现在单词中?如果我想在单词中允许另一个字符,如连字符,该怎么办?