我正在尝试限制一些可以在HTML中用于Markdown编辑器的锚标记的属性。这就是我现在所拥有的:
/^(<a\shref="((https?|ftp):\/\/|\/)[-A-Za-z0-9+&@#\/%?=~_|!:,.;\(\)]+"(\stitle="[^"<>]+")?\s?>|<\/a>)$/i
这允许锚标记具有title
和href
属性,但不允许其他任何属性。我还想添加target
但是我试过的任何东西都不起作用。
href
属性。title
属性,但不必。target
属性,但也不必包含。如何修改满足上述所有条件的正则表达式。
答案 0 :(得分:4)
通常,正则表达式不是解析某些语言的最佳工具。另一方面,如果你只想匹配一个孤立的锚标签,那么解析器可能会有点过多,而且正则表达式可以做得不错。
要将锚标记与您的要求相匹配,您可以使用下面的正则表达式。它使用反向引用来跟踪最多一个title
和一个target
(重复的属性),也至少/最多一个href
:
^(<a(?=[^>]*?(\s+href="((https?|ftp):\/\/|\/)[-A-Za-z0-9+&@#\/%?=~_|!:,.;\(\)]+")[^>]*>)(?=([^>]*?(\s+title="[^"<>]+"))?[^>]*>)(?=([^>]*?(\s+target="[^"<>]+"))?[^>]*>)(\2(\6\8?)?|\2\8\6?|\6\2\8?|\8\2\6?|\6\8\2|\8\6\2)\s*>[^<]*</a>)$
检查demo here,以及可以证明测试解决方案的数十个测试用例。
观察这个正则表达式并不是那么复杂(“丑陋”部分是URL,真的),但它非常全面并且需要处理:
href
属性title
属性target
属性href
,一个title
和一个target
。答案 1 :(得分:1)
RegEx-en 他们自己并不擅长此类事情。
我做的事情如下:
function validateAnchor(anchor){
var match,
name,
value,
test,
attrRE=/\s([a-z]+)(?:\s*=\s*"([^"]+))?"/gi, // matches one tag attribute
allowedAttrs={ // attributes must appear here to be considered legal
href:{
isValid:function(val){
return isValidURL(val);
}
},
title:{
isValid:function(val){
return true;
}
},
target:{
isValid:function(val){
return true;
}
}
},
result=true;
while(match=attrRE.exec(anchor)){
name=match[1].toLowerCase(); // lowerCase to match our allowedAttrs keys
value=match[2]||''; // optional
// must have a name
if(!name){
console.log('no name for this attr - should not happen!');
result=false;
break;
}
// and must exist in allowedAttrs
if(test=allowedAttrs[name]) {
console.log('unknown attr');
result=false;
break;
}
// if it has a value and there is am isValid function.
if(value && 'function'==typeof(attr.isValid)){
if(!attr.isValid(value)){ // which fails!
result=false;
break;
}
}
}
return result;
}
所以,给出了:
var anchor='<a href=\"...\" target = \"...\" foo >';
validateAnchor(anchor)将失败,因为&#39; foo&#39;是一个不允许的属性(未在allowedAttrs中定义)。
这种方法的好处在于你
我留下isValidURL()供您定义。
答案 2 :(得分:1)
让我们更容易:
/<a(?=.*href="((ht|f)tps?:\/)?\/.*")\s*((href|title|target)="[^"]*"\s*)*>[^<]*</a>/