2016-08-01 51 views
1

考慮以下字符串,如何使正則表達式中的前綴和捕獲字符是可選的?

var str = "<%= stylesheet_link_tag 'project/theme-one', media: 'all' if @auth.show? %>" 

下面的正則表達式返回一個有效匹配,

str.match(/\<%= stylesheet_link_tag\s+['"]?(.*)['"],.+if(.*)%\>/) 

// [ 
// "<%= stylesheet_link_tag 'project/theme-one', media: 'all' if @auth.show? %>", 
// "project/theme-one", 
// " @auth.show? " 
// ] 

但是,它未能與下面的字符串(不如果條件):

var str = "<%= stylesheet_link_tag 'project/theme-one', media: 'all' %>" 

// Expected result 
// [ 
// "<%= stylesheet_link_tag 'project/theme-one', media: 'all' if @auth.show? %>", 
// "project/theme-one", 
// " " 
// ] 

如何我可以讓if(.*)的正則表達式的一部分是可選的嗎?

+0

*爲0以上,我認爲這是什麼 「可選」 是指在這種情況下'' – m0skit0

+0

@ m0skit0沒了(如*)。 ,它會給出'[「<%= stylesheet_link_tag'項目/主題一',媒體:'全部'如果@ auth.show?%>」,「項目/主題一」,undefined,undefined]' – codef0rmer

+0

它匹配在我的測試中。你的意思是分組現在是不同的?你沒有問過關於分組。 – m0skit0

回答

2

一般而言,使一些圖案可選的(即,匹配的1或0次),則需要使用?量詞。如果您有一個符號,則可以在其後附加?。如果您有一系列子模式,最好的方法是將它們放入非捕獲組(?:...)並在其後添加?

您可以使用

<%= stylesheet_link_tag\s+['"]?(.*?)['"],.+?(?:if(.*))?%> 
           ^  ^^^^^^^^^^^^ 

regex demo

一個重要的一點這裏是第一.+太貪婪,吃了可選(?:if(.*))?部分。 .+應該與+?變懶。此外,爲了優化圖案,您還需要使用['"]?['"]之間的懶點匹配。

JS演示:

var re = /<%= stylesheet_link_tag\s+['"]?(.*?)['"],.+?(?:if(.*))?%>/g; 
 
var str = '<%= stylesheet_link_tag \'project/theme-one\', media: \'all\' if @auth.show? %>\n<%= stylesheet_link_tag \'project/theme-one\', media: \'all\' %>'; 
 

 
var res0 = []; 
 
var res1 = []; 
 
var res2 = []; 
 
    
 
while ((m = re.exec(str)) !== null) { 
 
res0.push(m[0]); 
 
res1.push(m[1]); 
 
res2.push(m[2]); 
 
} 
 
console.log(res0); 
 
console.log(res1); 
 
console.log(res2);

0

(if.*)*應該可以正常工作。完整的正則表達式:\<%= stylesheet_link_tag\s+['"]?(.*)['"],.+(if(.*))*%\>

Test

相關問題