Regex 如何拆分带有数字后缀的字符串?

Regex 如何拆分带有数字后缀的字符串?,regex,string,perl,Regex,String,Perl,我有一个输入字符串,我需要根据下面的要求拆分它 输入字符串: 1. "string" 2. "String 12343534" 3. "String_12343534" 4. "Stringone Stringtwo 12343534" 5. "Stringone Stringtwo_12343534" 6. "string 23string 12343534" 7. "string 23string_12343534" 8. "string_23string 1

我有一个输入字符串,我需要根据下面的要求拆分它

输入字符串:

  1. "string"
  2. "String 12343534"
  3. "String_12343534"
  4. "Stringone Stringtwo 12343534"
  5. "Stringone Stringtwo_12343534"
  6. "string 23string 12343534"
  7. "string 23string_12343534"
  8. "string_23string 12343534"
  9. "string_23string_12343534"
 10. "string 23string 4545stringthird 12343534"
 11. "string 23string 4545stringthird_12343534"
 12. "string_23string_stringthird_12343534"
 13. "string-23string-stringthird_12343534"
 14. "string_23string-stringthird_12343534" 
就像这样。和我必须分别拆分字符串和数字

输出应该是这样的

   1.  $str = "string" ; $num = ;
   2.  $str = "String" $num = "12343534";
   3.  $str = "String" $num = "_12343534";
   4.  $str = "Stringone Stringtwo" $num = "12343534";
   5.  $str = "Stringone Stringtwo" $num = "_12343534";
   6.  $str = "string 23string" $num = "12343534";
   7.  $str = "string 23string" $num = "_12343534";
   8.  $str = "string_23string" $num = "12343534";
   9.  $str = "string_23string" $num = "_12343534";
  10.  $str = "string 23string 4545stringthird" $num = "12343534";
  11.  $str = "string 23string 4545stringthird" $num = "_12343534";
  12.  $str = "string_23string_stringthird" $num = "_12343534";
  13.  $str = "string-23string-stringthird" $num = "_12343534";
  14.  $str = "string_23string-stringthird" $num = "_12343534";

有人能帮我吗?如何分割给定字符串以获得上述输出?

由于要保留所有内容,必须在锚定点上分割。您可以对此使用前瞻。按以下模式拆分:

(?=_\d)|\s+(?=\d)
因此:

如果数字前有下划线,它将在数字前拆分,否则它将在数字后的任何空格上拆分。这是正则表达式的翻译

您还可以使用以下选项:

(?=_\d+$)|\s+(?=\d+$)
这将通过强制匹配到字符串末尾来确保数字后面没有任何内容。如果末尾有非数字字符,则不会发生拆分

但只匹配您需要的内容比拆分IMO更容易:

my ($string, $numerical) = $input =~ /^(.*?)\s*(_?\d+)$/;

这更具可读性,更好地传达您的意图。

因为您想保留所有内容,所以必须在锚定点上拆分。您可以对此使用前瞻。按以下模式拆分:

(?=_\d)|\s+(?=\d)
因此:

如果数字前有下划线,它将在数字前拆分,否则它将在数字后的任何空格上拆分。这是正则表达式的翻译

您还可以使用以下选项:

(?=_\d+$)|\s+(?=\d+$)
这将通过强制匹配到字符串末尾来确保数字后面没有任何内容。如果末尾有非数字字符,则不会发生拆分

但只匹配您需要的内容比拆分IMO更容易:

my ($string, $numerical) = $input =~ /^(.*?)\s*(_?\d+)$/;

这更具可读性,更好地传达您的意图。

因为您想保留所有内容,所以必须在锚定点上拆分。您可以对此使用前瞻。按以下模式拆分:

(?=_\d)|\s+(?=\d)
因此:

如果数字前有下划线,它将在数字前拆分,否则它将在数字后的任何空格上拆分。这是正则表达式的翻译

您还可以使用以下选项:

(?=_\d+$)|\s+(?=\d+$)
这将通过强制匹配到字符串末尾来确保数字后面没有任何内容。如果末尾有非数字字符,则不会发生拆分

但只匹配您需要的内容比拆分IMO更容易:

my ($string, $numerical) = $input =~ /^(.*?)\s*(_?\d+)$/;

这更具可读性,更好地传达您的意图。

因为您想保留所有内容,所以必须在锚定点上拆分。您可以对此使用前瞻。按以下模式拆分:

(?=_\d)|\s+(?=\d)
因此:

如果数字前有下划线,它将在数字前拆分,否则它将在数字后的任何空格上拆分。这是正则表达式的翻译

您还可以使用以下选项:

(?=_\d+$)|\s+(?=\d+$)
这将通过强制匹配到字符串末尾来确保数字后面没有任何内容。如果末尾有非数字字符,则不会发生拆分

但只匹配您需要的内容比拆分IMO更容易:

my ($string, $numerical) = $input =~ /^(.*?)\s*(_?\d+)$/;

这更具可读性,更好地传达您的意图。

您可以尝试以下代码

my ($string, $numerical) = split / (?=\d+)|(?=_\d+)/, $str;

(?=\d+)
称为正向前瞻,它断言后面是一个下划线,后跟一个或多个数字。如果此条件为真,则正则表达式引擎将前面的匹配标记设置为
\ud+
。根据此零宽度匹配进行拆分将获得所需的结果

您可以尝试下面的代码

my ($string, $numerical) = split / (?=\d+)|(?=_\d+)/, $str;

(?=\d+)
称为正向前瞻,它断言后面是一个下划线,后跟一个或多个数字。如果此条件为真,则正则表达式引擎将前面的匹配标记设置为
\ud+
。根据此零宽度匹配进行拆分将获得所需的结果

您可以尝试下面的代码

my ($string, $numerical) = split / (?=\d+)|(?=_\d+)/, $str;

(?=\d+)
称为正向前瞻,它断言后面是一个下划线,后跟一个或多个数字。如果此条件为真,则正则表达式引擎将前面的匹配标记设置为
\ud+
。根据此零宽度匹配进行拆分将获得所需的结果

您可以尝试下面的代码

my ($string, $numerical) = split / (?=\d+)|(?=_\d+)/, $str;
(?=\d+)
称为正向前瞻,它断言后面是一个下划线,后跟一个或多个数字。如果此条件为真,则正则表达式引擎将前面的匹配标记设置为
\ud+
。根据此零宽度匹配进行拆分将获得所需的结果

由于您希望在数字字符和字母字符之间的边界上进行标记,因此需要使用

决定在何处包含下划线的附加规范并不完全清楚,但这是我对您意图的最好解释:

use strict;
use warnings;

while (<DATA>) {
    chomp;
    my @fields = split m{(?<=[a-z])\s*(?=_*\d)|(?<=\d)\s*(?=_*[a-z])}i, $_;

    use Data::Dump;
    dd @fields;
}

__DATA__
string 123456
string_45645645
stringone stringtwo 23435345345
string one string two_2335345345
由于您希望在数字字符和字母字符之间的边界上进行标记,因此需要使用

决定在何处包含下划线的附加规范并不完全清楚,但这是我对您意图的最好解释:

use strict;
use warnings;

while (<DATA>) {
    chomp;
    my @fields = split m{(?<=[a-z])\s*(?=_*\d)|(?<=\d)\s*(?=_*[a-z])}i, $_;

    use Data::Dump;
    dd @fields;
}

__DATA__
string 123456
string_45645645
stringone stringtwo 23435345345
string one string two_2335345345
由于您希望在数字字符和字母字符之间的边界上进行标记,因此需要使用

决定在何处包含下划线的附加规范并不完全清楚,但这是我对您意图的最好解释:

use strict;
use warnings;

while (<DATA>) {
    chomp;
    my @fields = split m{(?<=[a-z])\s*(?=_*\d)|(?<=\d)\s*(?=_*[a-z])}i, $_;

    use Data::Dump;
    dd @fields;
}

__DATA__
string 123456
string_45645645
stringone stringtwo 23435345345
string one string two_2335345345
由于您希望在数字字符和字母字符之间的边界上进行标记,因此需要使用

决定在何处包含下划线的附加规范并不完全清楚,但这是我对您意图的最好解释:

use strict;
use warnings;

while (<DATA>) {
    chomp;
    my @fields = split m{(?<=[a-z])\s*(?=_*\d)|(?<=\d)\s*(?=_*[a-z])}i, $_;

    use Data::Dump;
    dd @fields;
}

__DATA__
string 123456
string_45645645
stringone stringtwo 23435345345
string one string two_2335345345

就我个人而言,我发现使用
split
的解决方案有点过于复杂,而且它们似乎都无法处理以下字符串:

my $input = "code 4 you 12345678";
。。。我希望数字后缀是12345678,而不是“4”或“4you”

我更喜欢这样的东西:

my ($string, $numerical) = $input =~ /^ (.+?) \s* (_?\d+) $/x;
更新:我想我上面的解决方案已经涵盖了您的大部分upd