【发布时间】:2014-12-02 12:07:53
【问题描述】:
假设我有一个包含许多字符串的数组,称为 "birdBlue"、"birdRed" 和其他一些动物,如 "pig1"、"pig2")。
现在我运行一个遍历数组并返回所有鸟的 for 循环。什么比较在这里有意义?
Animals == "bird*" 是我的第一个想法,但不起作用。有没有办法使用运算符 * (或者有类似使用的东西?
【问题讨论】:
标签: javascript string comparison
假设我有一个包含许多字符串的数组,称为 "birdBlue"、"birdRed" 和其他一些动物,如 "pig1"、"pig2")。
现在我运行一个遍历数组并返回所有鸟的 for 循环。什么比较在这里有意义?
Animals == "bird*" 是我的第一个想法,但不起作用。有没有办法使用运算符 * (或者有类似使用的东西?
【问题讨论】:
标签: javascript string comparison
当你有一个rule 通配符字符串和一个text 字符串要匹配时:
function wcMatch(rule, text) {
return (new RegExp('^' + rule.replaceAll(/([.+?^=!:${}()|\[\]\/\\])/g, "\\$1").replaceAll('*', '(.*)') + '$')).test(text)
}
第一个replaceAll 转义特殊字符,第二个用(.*) 替换*(表达式表示“任何零个或多个字符”)
例如,一个字符串*&utm_*会被转换成一个表达式/^(.*)\&utm_(.*)$/
【讨论】:
我使用 @Spenhouet 的 answer 并添加了比“*”更多的“替换”可能性。例如 ”?”。只需将您的需求添加到 replaceHelper 中的字典即可。
/**
* @param {string} str
* @param {string} rule
* checks match a string to a rule
* Rule allows * as zero to unlimited numbers and ? as zero to one character
* @returns {boolean}
*/
function matchRule(str, rule) {
const escapeRegex = (str) => str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
return new RegExp("^" + replaceHelper(rule, {"*": "\\d*", "?": ".?"}, escapeRegex) + "$").test(str);
}
function replaceHelper(input, replace_dict, last_map) {
if (Object.keys(replace_dict).length === 0) {
return last_map(input);
}
const split_by = Object.keys(replace_dict)[0];
const replace_with = replace_dict[split_by];
delete replace_dict[split_by];
return input.split(split_by).map((next_input) => replaceHelper(next_input, replace_dict, last_map)).join(replace_with);
}
【讨论】:
该函数将通配符转换为正则表达式并进行测试(支持.和*通配符)
function wildTest(wildcard, str) {
let w = wildcard.replace(/[.+^${}()|[\]\\]/g, '\\$&'); // regexp escape
const re = new RegExp(`^${w.replace(/\*/g,'.*').replace(/\?/g,'.')}$`,'i');
return re.test(str); // remove last 'i' above to have case sensitive
}
function wildTest(wildcard, str) {
let w = wildcard.replace(/[.+^${}()|[\]\\]/g, '\\$&'); // regexp escape
const re = new RegExp(`^${w.replace(/\*/g,'.*').replace(/\?/g,'.')}$`,'i');
return re.test(str); // remove last 'i' above to have case sensitive
}
// Example usage
let arr = ["birdBlue", "birdRed", "pig1z", "pig2z", "elephantBlua" ];
let resultA = arr.filter( x => wildTest('biRd*', x) );
let resultB = arr.filter( x => wildTest('p?g?z', x) );
let resultC = arr.filter( x => wildTest('*Blu?', x) );
console.log('biRd*',resultA);
console.log('p?g?z',resultB);
console.log('*Blu?',resultC);
【讨论】:
replace 函数)——可能你有数字。看看 sn-p 里面 - 有例子
而不是 Animals == "bird*" Animals = "bird*" 应该可以工作。
【讨论】:
我认为您的意思是像“*”(星号)这样的通配符:
或在您的示例中:“bird*” => 以bird 开头的所有内容
我遇到了类似的问题,用 RegExp 写了一个函数:
//Short code
function matchRuleShort(str, rule) {
var escapeRegex = (str) => str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
return new RegExp("^" + rule.split("*").map(escapeRegex).join(".*") + "$").test(str);
}
//Explanation code
function matchRuleExpl(str, rule) {
// for this solution to work on any string, no matter what characters it has
var escapeRegex = (str) => str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
// "." => Find a single character, except newline or line terminator
// ".*" => Matches any string that contains zero or more characters
rule = rule.split("*").map(escapeRegex).join(".*");
// "^" => Matches any string with the following at the beginning of it
// "$" => Matches any string with that in front at the end of it
rule = "^" + rule + "$"
//Create a regular expression object for matching string
var regex = new RegExp(rule);
//Returns true if it finds a match, otherwise it returns false
return regex.test(str);
}
//Examples
alert(
"1. " + matchRuleShort("bird123", "bird*") + "\n" +
"2. " + matchRuleShort("123bird", "*bird") + "\n" +
"3. " + matchRuleShort("123bird123", "*bird*") + "\n" +
"4. " + matchRuleShort("bird123bird", "bird*bird") + "\n" +
"5. " + matchRuleShort("123bird123bird123", "*bird*bird*") + "\n" +
"6. " + matchRuleShort("s[pe]c 3 re$ex 6 cha^rs", "s[pe]c*re$ex*cha^rs") + "\n" +
"7. " + matchRuleShort("should not match", "should noo*oot match") + "\n"
);
如果您想了解更多关于使用的功能:
【讨论】:
matchRuleShort("https://evil.com", "https://*.il.com) 评估为真!为了防止这种情况,我必须用转义的等价物转义所有非 * 字符。 return new RegExp("^" + rule.replace(/[.?+^$[\]\\(){}|-]/g, "\\$&");.split("*").join(".*") + "$").test(str); 借用自 stackoverflow.com/a/2593661/238638 的正则表达式
您可以使用 Javascript 的 substring 方法。例如:
var list = ["bird1", "bird2", "pig1"]
for (var i = 0; i < list.length; i++) {
if (list[i].substring(0,4) == "bird") {
console.log(list[i]);
}
}
哪些输出:
bird1
bird2
基本上,您正在检查数组中的每个项目,以查看前四个字母是否为“鸟”。这确实假设 'bird' 将始终位于字符串的前面。
假设您从 URL 获取路径名:
假设您在 bird1?=letsfly - 您可以使用此代码检查 URL:
var listOfUrls = [
"bird1?=letsfly",
"bird",
"pigs?=dontfly",
]
for (var i = 0; i < list.length; i++) {
if (listOfUrls[i].substring(0,4) === 'bird') {
// do something
}
}
上面将第一个匹配到 URL,但不是第三个(不是猪)。您可以轻松地用正则表达式替换 url.substring(0,4),甚至可以使用 .contains() 等其他 javascript 方法
使用.contains() 方法可能更安全一些。您不需要知道 URL 'bird' 的哪一部分。例如:
var url = 'www.example.com/bird?=fly'
if (url.contains('bird')) {
// this is true
// do something
}
【讨论】:
document.url。
url.substring(0,4) 将为所有 3 个返回 http。也就是说,如果存在 url 变量 (var url = list[i])
var searchArray = function(arr, str){
// If there are no items in the array, return an empty array
if(typeof arr === 'undefined' || arr.length === 0) return [];
// If the string is empty return all items in the array
if(typeof str === 'undefined' || str.length === 0) return arr;
// Create a new array to hold the results.
var res = [];
// Check where the start (*) is in the string
var starIndex = str.indexOf('*');
// If the star is the first character...
if(starIndex === 0) {
// Get the string without the star.
str = str.substr(1);
for(var i = 0; i < arr.length; i++) {
// Check if each item contains an indexOf function, if it doesn't it's not a (standard) string.
// It doesn't necessarily mean it IS a string either.
if(!arr[i].indexOf) continue;
// Check if the string is at the end of each item.
if(arr[i].indexOf(str) === arr[i].length - str.length) {
// If it is, add the item to the results.
res.push(arr[i]);
}
}
}
// Otherwise, if the star is the last character
else if(starIndex === str.length - 1) {
// Get the string without the star.
str = str.substr(0, str.length - 1);
for(var i = 0; i < arr.length; i++){
// Check indexOf function
if(!arr[i].indexOf) continue;
// Check if the string is at the beginning of each item
if(arr[i].indexOf(str) === 0) {
// If it is, add the item to the results.
res.push(arr[i]);
}
}
}
// In any other case...
else {
for(var i = 0; i < arr.length; i++){
// Check indexOf function
if(!arr[i].indexOf) continue;
// Check if the string is anywhere in each item
if(arr[i].indexOf(str) !== -1) {
// If it is, add the item to the results
res.push(arr[i]);
}
}
}
// Return the results as a new array.
return res;
}
var birds = ['bird1','somebird','bird5','bird-big','abird-song'];
var res = searchArray(birds, 'bird*');
// Results: bird1, bird5, bird-big
var res = searchArray(birds, '*bird');
// Results: somebird
var res = searchArray(birds, 'bird');
// Results: bird1, somebird, bird5, bird-big, abird-song
这样的方法有一长串警告,还有一长串没有考虑到的“假设”,其中一些在其他答案中提到。但对于星型语法的简单使用,这可能是一个很好的起点。
【讨论】:
example: bird* 转换为良好的正则表达式。由 node.js 包管理器使用,因此它可能非常健壮。
if(mas[i].indexOf("bird") == 0)
//there is bird
您可以在此处阅读有关 indexOf 的信息:http://www.w3schools.com/jsref/jsref_indexof.asp
【讨论】:
bird 开头的长字符串有很大的开销。使用startsWith might be the better solution
你应该使用 RegExp(它们很棒)一个简单的解决方案是:
if( /^bird/.test(animals[i]) ){
// a bird :D
}
【讨论】: