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
Regex 检查字符串是否是一组字符的子集?(正则表达式)?_Regex_String_Perl_Subset - Fatal编程技术网

Regex 检查字符串是否是一组字符的子集?(正则表达式)?

Regex 检查字符串是否是一组字符的子集?(正则表达式)?,regex,string,perl,subset,Regex,String,Perl,Subset,我有一个小问题,我有8个字符,例如a b c d a e f g,还有一个单词列表,例如: 妈妈,爸爸,坏,同性恋,abac 我如何检查我是否能用我的字母写这些单词? 在我的例子中,我可以写bad、abac和fag,但我不能写爸爸我没有两个D,妈妈我没有M或O 我非常确定它可以使用正则表达式来完成,但即使使用Perl中的一些函数也会很有帮助。。 提前谢谢大家!: 伪代码: bool possible=true string[] chars= { "a", "b", "c"} foreach

我有一个小问题,我有8个字符,例如a b c d a e f g,还有一个单词列表,例如: 妈妈,爸爸,坏,同性恋,abac

我如何检查我是否能用我的字母写这些单词? 在我的例子中,我可以写bad、abac和fag,但我不能写爸爸我没有两个D,妈妈我没有M或O

我非常确定它可以使用正则表达式来完成,但即使使用Perl中的一些函数也会很有帮助。。 提前谢谢大家!:

伪代码:

bool possible=true
string[] chars= { "a", "b", "c"}   
foreach word in words
{
     foreach char in word.chars
     {
          possible=possible && chars.contains(char)
     }
}
伪代码:

bool possible=true
string[] chars= { "a", "b", "c"}   
foreach word in words
{
     foreach char in word.chars
     {
          possible=possible && chars.contains(char)
     }
}
这是为了证明这种可能性,而不是支持正则表达式方法。请考虑其他SANER解决方案。 第一步,您需要计算可用的字符数

然后构造您的正则表达式,因为这不是Perl代码

以输入锚的开头开始,这与列表中单个单词的字符串开头匹配:

^
根据唯一字符的数量添加以下内容:

(?!(?:[^<char>]*+<char>){<count + 1>})
例如:对于b c d a e f g,这将成为[abcdefg]+。这部分将实际使用该字符串,并确保该字符串仅包含列表中的字符

以输入锚点的结尾结束,该锚点与字符串的结尾匹配:

$
因此,对于您的示例,正则表达式将是:

^(?!(?:[^a]*+a){3})(?!(?:[^b]*+b){2})(?!(?:[^c]*+c){2})(?!(?:[^d]*+d){2})(?!(?:[^e]*+e){2})(?!(?:[^f]*+f){2})(?!(?:[^g]*+g){2})[abcdefg]+$
还必须为不区分大小写的匹配指定i标志

注意,这仅考虑英语字母表A -Z的单词匹配的情况。这里还没有考虑空格和连字符。

这是为了证明这种可能性,而不是支持正则表达式方法。请考虑其他SANER解决方案。 第一步,您需要计算可用的字符数

然后构造您的正则表达式,因为这不是Perl代码

以输入锚的开头开始,这与列表中单个单词的字符串开头匹配:

^
根据唯一字符的数量添加以下内容:

(?!(?:[^<char>]*+<char>){<count + 1>})
例如:对于b c d a e f g,这将成为[abcdefg]+。这部分将实际使用该字符串,并确保该字符串仅包含列表中的字符

以输入锚点的结尾结束,该锚点与字符串的结尾匹配:

$
因此,对于您的示例,正则表达式将是:

^(?!(?:[^a]*+a){3})(?!(?:[^b]*+b){2})(?!(?:[^c]*+c){2})(?!(?:[^d]*+d){2})(?!(?:[^e]*+e){2})(?!(?:[^f]*+f){2})(?!(?:[^g]*+g){2})[abcdefg]+$
还必须为不区分大小写的匹配指定i标志

注意,这仅考虑英语字母表A -Z的单词匹配的情况。此处未考虑空格和连字符。

一些伪代码:

bool possible=true
string[] chars= { "a", "b", "c"}   
foreach word in words
{
     foreach char in word.chars
     {
          possible=possible && chars.contains(char)
     }
}
将可用字符按字母顺序排序 对于每个单词:

将单词的字符按字母顺序排序 对于单词的每个字符,向前搜索可用字符以查找匹配字符。注意这一点 搜索将永远不会返回到可用字符的开头, 匹配的字符被消耗。 或者更好的是,使用字符的频率计数。 对于可用字符,构造一个从字符到该字符出现计数的映射。 对每个候选单词执行相同操作,并与可用映射进行比较,如果单词映射包含可用映射没有包含的字符映射,或者单词映射中的映射值大于可用映射,则无法使用可用字符构造单词。

某些伪码:

bool possible=true
string[] chars= { "a", "b", "c"}   
foreach word in words
{
     foreach char in word.chars
     {
          possible=possible && chars.contains(char)
     }
}
将可用字符按字母顺序排序 对于每个单词:

将单词的字符按字母顺序排序 对于单词的每个字符,向前搜索可用字符以查找匹配字符。注意这一点 搜索将永远不会返回到可用字符的开头, 匹配的字符被消耗。 或者更好的是,使用字符的频率计数。 对于可用字符,构造一个从字符到该字符出现计数的映射。
对每个候选单词执行相同操作,并与可用映射进行比较,如果单词映射包含可用映射不包含的字符映射,或者单词映射中的映射值大于可用映射,然后,无法使用可用字符构造单词。

如何将两个字符串按字母顺序排序,然后选择要插入的字符串* 在每个字母之间,如下所示:

'aabcdefg' =~ m/a.*b.*d.*/
True
'aabcdefg' =~ m/m.*m.*u.*/
False
'aabcdefg' =~ m/a.*d.*d.*/
False

将两个字符串按字母顺序排序,然后选择要插入的字符串* 在每个字母之间,如下所示:

'aabcdefg' =~ m/a.*b.*d.*/
True
'aabcdefg' =~ m/m.*m.*u.*/
False
'aabcdefg' =~ m/a.*d.*d.*/
False

最简单的方法是从要测试的单词中形成一个正则表达式

这将对可用字符列表进行排序,并通过连接这些字符形成字符串。然后将每个候选词拆分为字符,进行排序,并使用正则表达式项*作为分隔符重新连接。因此,例如,abac将转换为a.*a.*b.*c

然后,根据派生的正则表达式测试可用字符的字符串,从而确定单词的有效性

use strict;
use warnings;

my @chars = qw/ a b c d a e f g /;
my $chars = join '', sort @chars;

for my $word (qw/ mom dad bad fag abac /) {
  my $re = join '.*', sort $word =~ /./g;
  print "$word is ", $chars =~ /$re/ ? 'valid' : 'NOT valid', "\n";
}
输出


最简单的方法是从要测试的单词中形成一个正则表达式

这是李的分类 st是可用字符的一部分,并通过连接它们形成字符串。然后将每个候选词拆分为字符,进行排序,并使用正则表达式项*作为分隔符重新连接。因此,例如,abac将转换为a.*a.*b.*c

然后,根据派生的正则表达式测试可用字符的字符串,从而确定单词的有效性

use strict;
use warnings;

my @chars = qw/ a b c d a e f g /;
my $chars = join '', sort @chars;

for my $word (qw/ mom dad bad fag abac /) {
  my $re = join '.*', sort $word =~ /./g;
  print "$word is ", $chars =~ /$re/ ? 'valid' : 'NOT valid', "\n";
}
输出


下面是一个非常简单的脚本,很容易概括:

#!/usr/bin/env perl

use strict;
use warnings;

sub check_word {
  my $word = shift;
  my %chars;
  $chars{$_}++ for @_;
  $chars{$_}-- or return for split //, $word;
  return 1;
}

print check_word( 'cab', qw/a b c/ ) ? "Good" : "Bad";

当然,如果字母列表每次都是相同的,那么这个函数的性能会大大提高。实际上,对于8个字符,每次复制哈希与构建新哈希的速度可能是相同的。

这里有一个非常简单的脚本,很容易推广:

#!/usr/bin/env perl

use strict;
use warnings;

sub check_word {
  my $word = shift;
  my %chars;
  $chars{$_}++ for @_;
  $chars{$_}-- or return for split //, $word;
  return 1;
}

print check_word( 'cab', qw/a b c/ ) ? "Good" : "Bad";


当然,如果字母列表每次都是相同的,那么这个函数的性能会大大提高。实际上,对于8个字符,每次复制哈希与构建新哈希的速度可能是相同的。

可以强制正则表达式完成这项工作,但最好只进行计数。我从几个小时开始就对这项工作感到疯狂,你的意思是在性能或简单性方面更好?我认为简单的逻辑可以完成这项工作。你只处理英文字母表,对吗?是的,但我需要用一个由10个字符组成的字符串处理超过50万个单词,以检查我是否可以用10个字符创建每个单词,如果是,我必须打印每个单词。强制regex完成这项工作是可能的,但最好是只做计数。我从几个小时开始就对它发疯了,你的意思是性能更好还是更简单?我认为简单的逻辑可以完成这项工作。你只处理英文字母表,对吗?是的,但我需要用一个由10个字符组成的字符串处理超过50万个单词,以检查我是否可以用10个字符创建每个单词,如果是,我必须打印每个单词。你没有考虑计数。确切地说,双字母不被检查。。这非常简单^^你没有把计数考虑进去。确切地说,双字母是不被检查的。。这太简单了^^哦,天哪,疯狂的事!你是个怪物我马上就去试试!开始使用正则表达式的糟糕方法:@FedericoFallico:我似乎在传播糟糕的编码实践,因为我发布了一些显示可能性的东西……哦,天哪,这太疯狂了!你是个怪物我马上就去试试!开始使用正则表达式的糟糕方法:@FedericoFallico:我似乎在传播糟糕的编码实践,因为我发布了一些显示可能性的东西……难以置信,非常简单和有用,没有文字。谢谢:您在for语句中添加了500K+个单词?当然,好的,我不知道perl是否能很好地处理这些,所以不管您怎么想:难以置信,非常简单和有用,没有单词。谢谢:您在for语句中输入了500K+个单词?当然,好的,我不知道perl是否能很好地处理这个问题,所以不管您怎么想: