首页
学习
活动
专区
圈层
工具
发布

PCRE优化
EN

Stack Overflow用户
提问于 2010-11-22 15:11:01
回答 1查看 500关注 0票数 1

我正在尝试优化一个,或者至少知道是否有更好的方法来实现。

这是我的输入字符串:

代码语言:javascript
复制
$str = 'Some text
spanned on
several lines
txt_to_grab1 fixed_text1 txt_to_grab2
Full line to grab
txt_to_grab3 fixed_text2 txt_to_grab4
Some text after';

我试图抓住从"txt_to_grab1“到"txt_to_grab4”的线条,但只有"txt_to_grabX“和”全行抓取“。

我希望保留所有之前和之后未触及的内容(即换行),但删除我抓取的行中的行间隔(因为每一行都是一个<tr>,它将进入html表)。

Regex模式/替换-我找到匹配:

代码语言:javascript
复制
$find = "#(?<=\n)(.*?) fixed_text1 (.*?)(\n.*?\n)(.*?) fixed_text2 (.*?)(\n)#i";
$replace = '"$1" && "$2" grabbed.$3"$4" && "$5" grabbed.$6';   

$find = "#(.*)(?<=\n)(.*?) fixed_text1 (.*?)(\n)(.*)(?<=\n)(.*?) fixed_text2 (.*?)(\n.*)#is";
$replace = '$1"$2" && "$3" grabbed.$4$5"$6" && "$7" grabbed.$8';

问题:

所有问题都可以概括为:是否有更好/更短/更快的模式?

  • 如何使模式与\r\n或\n一起工作?我在堆栈的某个地方读到(\r?\n)将是一个解决方案,但我不知道如何在后面查找时使用它们。例如,下面的模式可以工作,但我不喜欢它们(只在查找后面使用脏\n,可能会产生意外的结果):

"#(?<=\n)(.*?)fixed_text1 (.*?)(\r?\n.*?r?\n)(.*?)fixed_text2 (.*?)(\r?\n)#i“(.*)(?<=\n)(.*?)fixed_text1 (.*?)(\r?\n)(.*)(?<=\n)(.*?)(.*?)(\r?\n.*)#is";

  • even更好的是,如何使用"s“修饰符从模式中删除所有的换行符,以便能够使用(.*?)但还是抓住了我想要的?单词边界?

  • 是多行模式(m修饰符)在这里有用/有用吗?

我真的很想解释一下正则表达式,如果你提供一些:)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-11-22 19:17:58

你不需要在后面找这个。只需在regex开始时使用行开始锚点,在末尾使用行尾锚(即多行模式下的^$ )。要匹配中间的行分隔符,可以使用(?:\r\n|[\r\n]),这是三种最常见的行分隔符的常见用法:\n\r\r\n

至于s修饰符(a.k.a )。“单行”或"DOT_ALL"),您也不需要这样做。它所做的就是允许点元字符匹配行分隔符以及所有其他字符,这对你没有任何好处。您希望它在到达换行时停止匹配,这样就可以将它们从捕获中排除在外。

下面是一个演示:

代码语言:javascript
复制
$pattern='#^(.*?) fixed_text1 (.*)(?:\r\n|[\r\n])(.*)(?:\r\n|[\r\n])(.*?) fixed_text2 (.*)$#im';

preg_match($pattern, $source, $m);

echo "$m[1] && $m[2] grabbed.\n";
echo "$m[3]\n";
echo "$m[4] && $m[5] grabbed.\n"; 

产出:

代码语言:javascript
复制
txt_to_grab1 && txt_to_grab2 grabbed.
Full line to grab
txt_to_grab3 && txt_to_grab4 grabbed.
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4246827

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档