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
Ruby 如何执行忽略控制字符的文本搜索?_Ruby_Regex_Search_Replace_Special Characters - Fatal编程技术网

Ruby 如何执行忽略控制字符的文本搜索?

Ruby 如何执行忽略控制字符的文本搜索?,ruby,regex,search,replace,special-characters,Ruby,Regex,Search,Replace,Special Characters,我有一个源字符串,它可以包含任何字符,包括空格、回车和换行符(控制字符)。控制字符可以出现在任何地方,包括单词的中间 我有一个搜索字符串,它可能具有与源字符串相同的字符选择,但通常是源字符串的子字符串。此搜索字符串中控制字符的顺序和数量可能与源不同 当搜索字符串中的非控制字符匹配时,我需要从源字符串中删除该字符串,包括该字符串中的任何控制字符。不应删除源字符串中其他位置的控制字符 我的计划是在搜索字符串中的每个字符后添加\s*。这很好,但是我需要转义搜索字符串中的任何正则表达式特殊字符,否则它们

我有一个源字符串,它可以包含任何字符,包括空格、回车和换行符(控制字符)。控制字符可以出现在任何地方,包括单词的中间

我有一个搜索字符串,它可能具有与源字符串相同的字符选择,但通常是源字符串的子字符串。此搜索字符串中控制字符的顺序和数量可能与源不同

当搜索字符串中的非控制字符匹配时,我需要从源字符串中删除该字符串,包括该字符串中的任何控制字符。不应删除源字符串中其他位置的控制字符

我的计划是在搜索字符串中的每个字符后添加
\s*
。这很好,但是我需要转义搜索字符串中的任何正则表达式特殊字符,否则它们将被视为正则表达式命令,而不是真正的纯文本

我可以在每个字符(
'mytext.scan(/./).join(\\s*)”
之后添加
\s*
),但是如何转义特殊字符而不是插入的正则表达式代码?如果我用另一种方法,那么我可以转义正则表达式特殊字符,但我不能简单地在每个字符后添加
\s*
;我需要避免转义字符

为了清楚起见 控制字符=空格或\t或\r或\n或\f

编辑:修改第3段以提高我的需求的清晰性

1) 将搜索字符串拆分为单个字符的列表(每个字符都是字符串)

2) 清理每个字符(仍然是字符串列表)

3) 通过
\s*
*

*除了
\s*
不起作用之外,顺便说一下-
\s*
将匹配0个或更多的空白,这与0个或更多的控制字符不同。请参阅,并使用适用于正则表达式风格的“控制字符”形式:)


\W*
也可以,因为
\W
是a-zA-Z0-9中没有的任何字符。但我从未测试过是否匹配控制字符或仅匹配可打印字符。

如注释中所述:


复制源字符串和搜索字符串。从两个副本中删除所有控制字符。使用源字符串副本中的搜索字符串副本进行搜索。如果需要,也可以进行大小写转换(或重音消除,或…)。使用大量的
\s*
可能会大大降低正则表达式的速度


搜索字符串只需复制和预处理一次。每个源字符串也需要复制和预处理一次。如果出现最坏的情况,当您知道存在匹配项时,您可以返回原始源字符串并创建搜索字符串的新副本,以便在每个常规字符之间都有类似于
\s*
的内容,并将搜索字符串的第二个(残缺的)副本中的正则表达式应用于原始源字符串。因为您知道存在匹配,所以性能应该是合理的,即使失败匹配模式会太慢

下面是所讨论思想的Perl实现

#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;

$Data::Dumper::Useqq = 1;

my $source = "'Twas (Tweedle-Dee's)\fBirthday\n\n\f\f\nand\ta\tl\tl\this friends were happy\n";
my $search = "(\fTwee\ndle\t-\tDee\r'\rs)\nBi\frth\fday";

print Data::Dumper->Dump([$source], [qw($source)]);
print Data::Dumper->Dump([$search], [qw($search)]);

my $c_source = $source;
my $c_search = $search;

$c_source =~ s/ |[[:cntrl:]]//g;    # Or s/\s//g;
$c_search =~ s/ |[[:cntrl:]]//g;    # Or s/\s//g;

print Data::Dumper->Dump([$c_source], [qw($c_source)]);
print Data::Dumper->Dump([$c_search], [qw($c_search)]);

if ($c_source =~ m/\Q$c_search\E/)
{
    # Locating the search in the original source...hard work...
    my @a_search = split //, $c_search;
    printf "Lengths: c_search %d; a_search %d\n", length($c_search), scalar(@a_search);

    @a_search = map { s/[][\\.*?+(){}]/\\$&/g; $_ } @a_search;   # Escape regex metacharacters
    #print Data::Dumper->Dump([\@a_search], [qw(@a_search)]);
    my $r_search = join "\\s*", @a_search;
    print Data::Dumper->Dump([$r_search], [qw($r_search)]);

    my $t_source = $source;
    $t_source =~ s/$r_search//g;
    print Data::Dumper->Dump([$t_source], [qw($t_source)]);
}
好干净的象形文字乐趣-毫无疑问,像泥一样清晰。前三行检查没有任何愚蠢的错误。
Data::Dumper
模块清晰地打印数据;它是用来调试的。
Useqq
变量调整数据的打印方式

变量
$source
$search
是源字符串和搜索字符串。这是一个匹配,尽管每个控件中都有所有的控制字符。请注意,混合中有一些正则表达式元字符-括号是正则表达式元字符。这些字符串被转储以供参考

接下来的两行复制了搜索字符串和源字符串。将使用基于POSIX的正则表达式类来指定所有控制字符,从而删除控制字符和空格。将这些转换后的管柱倾倒以供检查

if
语句将转换的源与转换的搜索进行比较。
\Q..\E
部分抑制介于两者之间的正则表达式元字符的含义。如果有匹配项,那么我们就用大括号输入代码块

split
操作从转换后的搜索字符串创建一个单个字符数组。
printf
检查是否正常。
map
操作用反斜杠和元字符替换每个正则表达式元字符,其他字符保持不变。
join
将数组
@a\u search
中的每个字符或字符对收集到字符串
$r\u search
,并用
\s*
分隔数组条目

变量
$t_source
是源代码的另一个副本。
$r\u search
中的正则表达式应用于
$t\u search
,任何匹配项都将被替换为零。结果被转储。此脚本的输出为:

$source = "'Twas (Tweedle-Dee's)\fBirthday\n\n\f\f\nand\ta\tl\tl\this friends were happy\n";
$search = "(\fTwee\ndle\t-\tDee\r'\rs)\nBi\frth\fday";
$c_source = "'Twas(Tweedle-Dee's)Birthdayandallhisfriendswerehappy";
$c_search = "(Tweedle-Dee's)Birthday";
Lengths: c_search 23; a_search 23
$r_search = "\\(\\s*T\\s*w\\s*e\\s*e\\s*d\\s*l\\s*e\\s*-\\s*D\\s*e\\s*e\\s*'\\s*s\\s*\\)\\s*B\\s*i\\s*r\\s*t\\s*h\\s*d\\s*a\\s*y";
$t_source = "'Twas \n\n\f\f\nand\ta\tl\tl\this friends were happy\n";
字符串
$t_source
确实对应于
$source
,删除了“(特威德·迪的)生日”,这似乎符合要求

将其转换为Ruby是受虐狂^H^H^H^H^H^H^H^H^H^H^H^H^H^H感兴趣的读者的一个练习


显然,您可以简单地创建并使用
$r_search
字符串作为正则表达式,并将其直接应用于
$source
的(副本);这会奏效的。但我非常怀疑,如果将其应用于KB长度的源字符串,代码将运行得非常慢。不过,我还没有通过测量来证明这一点。

复制源字符串和搜索字符串。从两个副本中删除所有控制字符。使用源字符串副本中的搜索字符串副本进行搜索。如果需要,也可以进行案例转换(或