【问题标题】:Notepad++ and regex with removal of unmatching sections删除不匹配部分的 Notepad++ 和正则表达式
【发布时间】:2018-05-23 04:52:57
【问题描述】:

我正在使用我制作的这个正则表达式字符串...

['"]{1}\w+@\w+\.{1}\w\w\w?['"]

在格式错误的旧文件中寻找包含在引号中的电子邮件地址。

例子:

 ADF325@#%jkdaf-@#%j-afd(#$w52'leroyjenkins@myguild.edu'@#%kladfjkla-235dsaf-'thisemail@example.com'2l35jk2dz-dl1jkozf-afajelj'gooselick@somebodyspastries.co'l2#%Jk23l5jlafafljewo8972509357
j2k3l5jadfjeljwfoobar'foobar@barfoo.foo'jk23j-zv8902354jlfa
('352lj53k2ljkumquat'fakeemail@realemail.wtf')lajflsdf
etc.

正则表达式对我来说工作得很好......除了一件事。我想用空格替换所有不匹配的内容,以便我可以对其进行格式化以将其迁移到正确的数据库。如何删除所有不匹配的内容(最好在每个匹配项之间添加一个换行符)?

【问题讨论】:

标签: regex replace notepad++


【解决方案1】:

使用

['"](\w+@\w+\.\w{2,3})['"]|(?s).

并替换为(?{1}\1\n)

等价的更快一点 (demo):

['"](\w+@\w+\.\w{2,3})['"]|[^'"]*(?:['"](?!\w+@\w+\.\w{2,3}['"])[^'"]*)*

详情

  • ['"] - 引用
  • (\w+@\w+\.\w{2,3}) - 第 1 组:1+ 个单词字符,@,1+ 个单词字符,.,然后是 2 或 3 个单词字符
  • ['"] - 引用
  • | - 或
  • (?s). - 任何单个字符。

如果第 1 组匹配 ((?{1}),则匹配将替换为第 1 组内容 (\1\n)。如果(?s). 匹配,则匹配被删除。

【讨论】:

  • 试过了,只是记事本++崩溃了。
  • @liljoshu 不要尝试,使用它。查看我的设置窗口,其中包含示例替换结果。
  • 看起来它可能只是由于它试图解析的文件的大小而崩溃。我将它分成块并再次尝试使用。
  • @liljoshu This regex variation 会更快。我将其添加到答案中。
  • 太好了,它并没有使 notepad++ 崩溃...减慢我的系统速度并花费很长时间来处理,但不会崩溃(文件相当大)。一旦它完成了所有的咀嚼,我将给出这个正确的答案投票,假设它有效,我猜它会在这一点上。
【解决方案2】:

当您必须处理大文件时,处理它们的方法包括不完全加载它们。相反,您必须将它们作为流读取。使用 npp 无法做到这一点,但可以使用 php 之类的脚本语言。 如果您想进行更改或特别是在将文件作为流加载时提取某些内容,您可以编写用户定义的流过滤器:

class EmailFilter extends php_user_filter
{
    public function filter($in, $out, &$consumed, $closing)
    {
        while ( $bucket = stream_bucket_make_writeable($in) ) {
            if ( preg_match_all('~\'\K\w+@\w+\.\w{2,3}(?=\')|"\K\w+@\w+\.\w{2,3}(?=")~S', $bucket->data, $matches) ) {
                 $bucket->data = implode("\n", $matches[0]);    
            }
            $consumed += $bucket->datalen;
            stream_bucket_append($out, $bucket);
        }
        return PSFS_PASS_ON;
    }
}

stream_filter_register('email_filter', 'EmailFilter');
$handle = fopen('php://filter/read=email_filter/resource=yourfile.txt', 'rb');

while (feof($handle) !== true) {
    echo fgets($handle); 
}

fclose($handle);

当您采用这种方法时,没有什么可以禁止在您的表中插入邮件,即 5 个 5 个、10 个 10 个、20 个 20 个或您想要的数字。目标是不加载内存中的所有文件。

(O'Reilly Modern PHP 中的更多示例)

【讨论】:

  • 在将文件分成几部分后(这是一次性的情况),已经成功使用其他解决方案,但你的答案非常好,特别是如果我不得不重复这样做的话。
  • @liljoshu:主要优点是内存占用少。即使你必须做一次,但由于文件大小,你的系统已经瘫痪,这需要很多时间。
  • 因为它看起来不错(而且我也是 PHP 编码员),所以我决定尝试一下您的脚本……结果它返回了包含电子邮件地址的整行,而不仅仅是电子邮件,因此它导致输出与输入几乎相同。
  • @liljoshu:你错过了一些东西,因为我得到了确切的信息:leroyjenkins@myguild.edu thisemail@example.com gooselick@somebodyspastries.co foobar@barfoo.foo fakeemail@realemail.wtf 不多不少。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-31
  • 1970-01-01
  • 2010-09-09
  • 2011-06-13
  • 1970-01-01
  • 1970-01-01
  • 2017-11-29
相关资源
最近更新 更多