新人求助一个正则表达式的问题

sceislqzw 2012-10-25 10:06:29
大家好,对于正则表达式只是简单的知道一些语法,今天碰到一个优点难的问题,花了好长时间还是写不出来,只能来这里求教了,希望大家能帮我一下。

需求是这样的,我在一堆字符串中 要在这堆中找出字符串中 同时包含了 "string1"和"string2" 的字符串,而且这堆字符串中可能有换行之类的。

example:
1:
123123123 ...string1 ....23123123
.....
2323 string2...1231555

2: 23123string2......
123123123string11234555

3: string112312409
sdfasdfsdfsdf

4: sdfsdfasdfsdfsstring2....

如何用一个正则表达式,让结果返回1和2?
...全文
180 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
Mr-Jee 2012-10-26
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 的回复:]

楼上的处理是有问题的,先出现string2然后出现string1也是符合要求的
[/Quote]你是在说我的么?
  • 打赏
  • 举报
回复
楼上的处理是有问题的,先出现string2然后出现string1也是符合要求的
Mr-Jee 2012-10-26
  • 打赏
  • 举报
回复
4楼似乎把需求复杂化了。不过反而更有意思了。要不我开个帖子大家一起玩玩?
Mr-Jee 2012-10-26
  • 打赏
  • 举报
回复

var s = [
'2: 23123string2......\n'
+'123123123string11234555\n' ,
'1:\n'
+'123123123 ...string1 ....23123123\n'
+'....\n.'
+'2323 string2...1231555\n' ,

'3: string112312409\n'
+'sdfasdfsdfsdf\n' ,

'4: sdfsdfasdfsdfsstring2....',
];

var reg = /^(?=[\S\s]*string1)(?=[\S\s]*string2)/;
for (var i = 0, length = s.length; i < length; i++) {
console.log(reg.test(s[i]));
}
  • 打赏
  • 举报
回复
4楼的做法比较高效, 但indexOf有些情况下会产生误判。
其实真实环境中可能的需求是这样的:查找同时包含两
个关键字的配置项。

这时候indexOf很容易产生误判。如果关键字换一下换成
string1 string2 那么包含string12 string21的就会被匹配。
当然了如果只是模糊匹配的话这倒无所谓。
  • 打赏
  • 举报
回复
那个正则还有优化的余地,当时写的比较仓促其实玩去可以用match来代替exec的。
但如果你完全用正则的话,根本无法将问题扩展到多个关键字的情况,你写个同时
包含5个关键字的正则试试。但如果把问题拆分的话可以很方便的处理任意关键字。
Vidor 2012-10-26
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

就这个需求来说,完全用正则来解的话并不合适
JScript code
'use strict';

var s = (
'1:\n'
+'123123123 ...string1 ....23123123\n'
+'....\n.'
+'2323 string2...1231555\n'

+'2: 23123string2......\n'
+'123123123……
[/Quote]

搞得那么复杂,还真不如完全用正则,优雅有余性能稍欠。

8楼正则的缺点是回溯太多,正则的效率取决于对文本的了解,楼主给的文本太抽象导致正则也只能抽象,回溯免不了。

不过确实[^:]*贪婪改为[^:]*?非贪婪会好点,因为string1/2的问题可能要扫两次,所以还是比你的cfgPatten慢,但是用正则扫完结果就出来了,而你还要调用一堆对象处理,所以断言性能稍欠(我未测试过)。

综合性能最好应该是4楼 showbo 的,split、indexOf测试,不涉及回溯。
  • 打赏
  • 举报
回复
就这个需求来说,完全用正则来解的话并不合适
'use strict';

var s = (
'1:\n'
+'123123123 ...string1 ....23123123\n'
+'....\n.'
+'2323 string2...1231555\n'

+'2: 23123string2......\n'
+'123123123string11234555\n'

+'3: string112312409\n'
+'sdfasdfsdfsdf\n'

+'4: sdfsdfasdfsdfsstring2....'
);

var m, cfgName, cfgVal, kws, a = [];
var cfgPatten = /(\d+):([\S\s]+?)(?=(\d+:|$))/g;
var kwPatten = /string\d/g;
var mastInc = ['string1', 'string2'];

var contains = function(a, items){
var inArray = (
Array.prototype.indexOf
? function(a, v){
return a.indexOf(v) != -1;
}

: function(a, v){
var i, len = a.length;
for(i=0; i<len; i++){
if(a[i] == v){
return true;
}
}
return false;
}
);

var i, c, len = items.length;
for(i=0, c=0; i<len; i++){
if( inArray(a, items[i]) ){
c++;
}
}

return c == len;
}


while( m = cfgPatten.exec(s) ){
cfgName = m[1];
cfgVal = m[2];
kws = cfgVal.match(kwPatten);

if( contains(kws, mastInc) ){
a.push(cfgName);
}
}

console.log(a);
泡泡鱼_ 2012-10-26
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]
看了4楼的回复,我凌乱了,你的example 1,2,3,4 是1个字符串还是4个字符串,4个字符串3楼的正则测试再处理是没问题的,1个字符串正则:

JScript code

var s='1:\n'
+'123123123 ...string1 ....23123123\n'
+'....\n.'
+'2323 string2...1231555\n'

+'2: 2312……
[/Quote]
写得真是超优雅。[PS:不嫌麻烦的话解释一下吧,我用(\w+)去拼接,死活不对]

4楼 showbo 写的好像在处理的时候有点小问题需要修正一下

var a=/\w+:/g,b=s.match(a),c=s.split(a),d=[];
for(var i=0;i<b.length;i++){
if(c[i].indexOf('string1')!=-1 && c[i].indexOf('string2')!=-1){
d.push(b[i].replace(':',''));
}
};
alert(d);
Vidor 2012-10-25
  • 打赏
  • 举报
回复
看了4楼的回复,我凌乱了,你的example 1,2,3,4 是1个字符串还是4个字符串,4个字符串3楼的正则测试再处理是没问题的,1个字符串正则:

var s='1:\n'
+'123123123 ...string1 ....23123123\n'
+'....\n.'
+'2323 string2...1231555\n'

+'2: 23123string2......\n'
+'123123123string11234555\n'

+'3: string112312409\n'
+'sdfasdfsdfsdf\n'

+'4: sdfsdfasdfsdfsstring2....'

var re = /^\d+(?=:[^:]*(?:string1[^:]*string2|string2[^:]*string1))/gim

alert(s.match(re)) //1, 2
sceislqzw 2012-10-25
  • 打赏
  • 举报
回复
我在想是不是我的问题可以简化成 正则里面怎么写“所有字符数字制表符”?
sceislqzw 2012-10-25
  • 打赏
  • 举报
回复
应该是3楼,数楼数错了-_-!!!
sceislqzw 2012-10-25
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

还新人,这么变态的要求。。没想出来。。暂时的解决办法。。

HTML code
<script>

var s='1:\n'
+'123123123 ...string1 ....23123123\n'
+'....\n.'
+'2323 string2...1231555\n'

+'2: 23123string2......\n'
+'123123123string11234555\n……
[/Quote]
结果是对了,但是我想要一个正则……

我想了想 也看了下4楼朋友的,得出下面这样一个正则:
(string1+(.*\n*.*)*string2+)|(string2+(.*\n*.*)*string1+)

但是在我一个测试程序里面运行,死后不对啊,是不是我语法错了,还是不同编程语言直接的换行符不对?还是正则太复杂了?
Go 旅城通票 2012-10-25
  • 打赏
  • 举报
回复
还新人,这么变态的要求。。没想出来。。暂时的解决办法。。

<script>

var s='1:\n'
+'123123123 ...string1 ....23123123\n'
+'....\n.'
+'2323 string2...1231555\n'

+'2: 23123string2......\n'
+'123123123string11234555\n'

+'3: string112312409\n'
+'sdfasdfsdfsdf\n'

+'4: sdfsdfasdfsdfsstring2....'




var rx=/\d+:/g,split=s.match(rx),rst=[],arr=s.split(rx);
for(var i=1;i<arr.length;i++)
if(arr[i].indexOf('string1')!=-1&&arr[i].indexOf('string2')!=-1)rst[rst.length]=split[i-1].replace(':','');

alert(rst)


</script>
Vidor 2012-10-25
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

这个貌似有换行的就不支持,是不是需要有什么额外的设置?
[/Quote]

哦对\n

var re = /string1[\s\S]*string2|string2[\s\S]*string1/i
sceislqzw 2012-10-25
  • 打赏
  • 举报
回复
这个貌似有换行的就不支持,是不是需要有什么额外的设置?
Vidor 2012-10-25
  • 打赏
  • 举报
回复
var re = /string1.*string2|string2.*string1/i
if (re.test(str)) ...

87,910

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧