Regex Perl正则表达式:如何获取相同的部分

Regex Perl正则表达式:如何获取相同的部分,regex,perl,pcre,Regex,Perl,Pcre,我正在为一些游戏创建一个阶梯系统,我遇到了一个关于氏族基础系统的问题。你看,每个加入的玩家都会被解析并放入一个玩家表中。像这样: chelsea | gordon chelsea | jim chelsea | brad 或者 所以,我想要的是:我想要抓到这个家族标签,它在同一个地方,每个球员的名字都是一样的,都在那个队。但是,分隔符可以是空白或空白(clan player1、clan player2或clan player1、clan player2) 有什么办法吗 提前谢谢。在这里大刀阔

我正在为一些游戏创建一个阶梯系统,我遇到了一个关于氏族基础系统的问题。你看,每个加入的玩家都会被解析并放入一个玩家表中。像这样:

chelsea | gordon 
chelsea | jim
chelsea | brad
或者

所以,我想要的是:我想要抓到这个家族标签,它在同一个地方,每个球员的名字都是一样的,都在那个队。但是,分隔符可以是空白或空白(clan player1、clan player2或clan player1、clan player2)

有什么办法吗


提前谢谢。

在这里大刀阔斧,这是你想要的吗

#! /usr/bin/perl

use strict;
use warnings;

while (<DATA>)
{
  if (/^(\w+) \| (\w+)$/     ||
      /^\[(\w+)\] \. (\w+)$/ ||
      /^(\w+)-(\w+)$/)
  {
    print "tag=$1, name=$2\n";
  }
}

exit 0;

__DATA__
team1 | foo
team1 | bar

[another] . user
[another] . player

more-james
more-brown

编辑:重新阅读问题和评论

这适用于示例,但可能不适用于带有空格或标点符号的名称,也可能不适用于其他情况:

while ( <DATA> )
{
    if ( /(\w+).*?(\w+)$/ )
    {
        print "$1, $2\n";
    }
}


__DATA__
team1 | foo
team1 | bar

[another] . user
[another] . player

more-james
more-brown

如果一次只以一个玩家的名字运行正则表达式,我建议:

/(\w+)\W+(\w+)$/
在英语中,这表示“至少一个单词字符,后跟至少一个非单词字符,后跟至少一个单词字符,然后是行尾”

“单词字符”是字母、数字和下划线。因此,如果人们在标签/刻痕中使用除这些字符以外的任何字符,则需要修改。例如,如果人们的刻痕中可能也有连字符,则您需要:

/(\w+)\W+([\w-]+)$/
据我所知,人们总是使用标点符号类型的字符(和/或空格)来分隔他们的部族和尼克,所以那里的\W+应该很好

至于你给出的没有分隔符的例子(clanplayer1,clanplayer2),如果不查看多个玩家的名字,你知道他们在同一个氏族中,并且找出他们的名字在什么时候开始不同,那么解决这个问题就没有办法了,所以单用正则表达式是无法解决的。

这里有一个例子:

use strict;
use warnings;

my($strip) = shift || 0;

print FindTeamName("TEAMJimBob", "TEAMJoeBob", "TEAMBillyBob"), "\n";
print FindTeamName("TEAM|JimBob", "TEAM|JoeBob", "TEAM|BillyBob"), "\n";
print FindTeamName("TEAM | JimBob", "TEAM | JoeBob", "TEAM | BillyBob"), "\n";
print FindTeamName("TEAMJimBob", "TEAM|JoeBob", "TEAM - BillyBob"), "\n";

sub FindTeamName
{
    my(@players) = @_;

    my($team) = shift;
    foreach my $player (@players) {
        $team = FindCommonString($team, $player);
    }

    $team =~ s{\W+$}{} if $strip;

    $team;
}

sub FindCommonString
{
    my($str1, $str2) = @_;

    my(@arr1) = split(//, $str1);
    my(@arr2) = split(//, $str2);

    my($common) = "";

    while (@arr1 && @arr2) {
        my($letter1) = shift(@arr1);
        my($letter2) = shift(@arr2);

        if ($letter1 eq $letter2) {
            $common .= $letter1;
        }
        else {
            last;
        }
    }

    $common;
}
其中给出了以下内容:

C:\temp>perl test.pl
TEAM
TEAM|
TEAM |
TEAM

C:\temp>perl test.pl 1
TEAM
TEAM
TEAM
TEAM

C:\temp>

这里的团队名称是“团队1”、“另一个”和“更多”?我认为问题在于每个人都使用了不同的格式,或者存在少量的可能性?请稍微澄清一下这个问题-不清楚要捕获哪些数据。是的;请显示示例输入和您希望发生的事情。i、 e.“给定{foo}{bar},我想要数组[qw/foo-bar/]”。然后我们可以帮助。是的,分隔符是不同的,就像我在下面的评论中写的,它可以是从空白到空白的所有内容。我想要的是标签,不是球员的名字。就像TEAMplayer1和TEAMplayer2一样,我想抓住球队。对于tag-user,tag-user2,我想抓取“tag”。不完全是,因为分隔符不同。它可以是任何内容,从空白到空白,就像TEAMplayer1、TEAMplayer2一样。我还想抓住标签,而不是球员的名字。:)好的,如果你对格式更具体一点,答案会更接近你需要的。格式?就像我说的,它可以是一切,我们唯一知道的是,它是每个团队成员名字的一个相等部分。啊,我明白了-你在左边寻找一些跨越多条线的共同点。这有点难…是的,这是可能的。您只需要在任意行组之间查找最左边最长的公共子字符串。但这并不容易。啊,错过了无分离器的案例。如果您有teamjones和teamjoe,那么就无法知道团队名称是否为“团队”、“teamj”、“teamjo”等。这还不错,事实上,我在数据库中存储的每个团队中都使用了该名称。如果我们在上面添加一点故障保护功能,它可能正是我所需要的:)Thanks我认为他想要得到团队名称,所以对于“fooA”和“fooB”,他想要提取“foo”,即最长最左的通用性,当然要忽略任何格式/分隔符垃圾。
/(\w+)\W+([\w-]+)$/
use strict;
use warnings;

my($strip) = shift || 0;

print FindTeamName("TEAMJimBob", "TEAMJoeBob", "TEAMBillyBob"), "\n";
print FindTeamName("TEAM|JimBob", "TEAM|JoeBob", "TEAM|BillyBob"), "\n";
print FindTeamName("TEAM | JimBob", "TEAM | JoeBob", "TEAM | BillyBob"), "\n";
print FindTeamName("TEAMJimBob", "TEAM|JoeBob", "TEAM - BillyBob"), "\n";

sub FindTeamName
{
    my(@players) = @_;

    my($team) = shift;
    foreach my $player (@players) {
        $team = FindCommonString($team, $player);
    }

    $team =~ s{\W+$}{} if $strip;

    $team;
}

sub FindCommonString
{
    my($str1, $str2) = @_;

    my(@arr1) = split(//, $str1);
    my(@arr2) = split(//, $str2);

    my($common) = "";

    while (@arr1 && @arr2) {
        my($letter1) = shift(@arr1);
        my($letter2) = shift(@arr2);

        if ($letter1 eq $letter2) {
            $common .= $letter1;
        }
        else {
            last;
        }
    }

    $common;
}
C:\temp>perl test.pl
TEAM
TEAM|
TEAM |
TEAM

C:\temp>perl test.pl 1
TEAM
TEAM
TEAM
TEAM

C:\temp>