稍微解释一下情况;我们有一个非标准文字时间和日期字符串,它们之间存在很大差异,需要解析到XDate
(http://arshaw.com/xdate/)对象中(可能有多个XDate
个对象。
请注意我不是在寻找完全编写代码的人。只是一些理论和快速代码片段来处理所有可能的情况(即使失败)。此外,这不是家庭作业。
我的第一个解决方案是使用split()
,但失败了。我调查的其他一些可能性包括regex
,pattern matching
,loop text until not ascii
,number picker from string
等。
失败后,我很可能只会产生一些随机营业时间 避免失败尤为重要。
我不确定最佳方法会是什么。 非常感谢任何和所有帮助。
这里有一些可能性。每一行代表一种可能性。
日期和时间:
的结果:
输出将是格式为JSON
的对象:
{
mon_open: "6:00 am",
mon_close: "8:00 pm",
tue_open: "6:00 am",
tue_close: "8:00 pm",
etc
}
答案 0 :(得分:2)
我建议你先把日期字符串格式化为电脑更易理解的东西(更标准化),然后你就可以轻松地扯掉你需要的部分:
http://jsfiddle.net/DerekL/8L5EA/
以下代码会将您的日期字符串修改为标准格式:
["monday+tuesday+wednesday+thursday+friday06:00-20:00"]
["monday+wednesday+friday12:00-21:00"]
["monday+tuesday+wednesday+thursday+sunday11:00-20:00"]
["monday11:00-20:30", "tuesday11:00-20:30", "wednesday11:00-20:30", "thursday11:00-20:30", ""]
[ d[+d...]HH:MM-HH:MM , d[+d...]HH:MM-HH:MM , ... ]
然后它将根据此标准化字符串创建对象。
http://jsfiddle.net/DerekL/8L5EA/
console.log(makeObj(txt)); //<-- Here is your object
function makeObj(txt) {
arr = formatText(txt);
var result = {};
for (var i = 0; i < arr.length; i++) {
var times = arr[i].match(/\d\d:\d\d-\d\d:\d\d/);
if (times === null) {
continue;
}
times = times[0].split("-");
var days = arr[i].match(/(\D+)\d\d:\d\d-\d\d:\d\d/)[1].split("+");
for (var j = 0; j < days.length; j++) {
result[days[j] + "_open"] = times[0];
result[days[j] + "_close"] = times[1];
}
}
return result;
}
function addZeros(n) {
return ("0" + n).slice(-2);
};
function formatText(txt) {
//remove spaces
var output = txt.replace(/\s/g, "");
//change abbr. to full name
output = output.toLowerCase().replace(/(mon|tues|tue|wed|thurs|thur|thu|fri|sat|sun)(?![a-z])/g, function (c) {
return {
mon: "monday",
tue: "tuesday",
tues: "tuesday",
wed: "wednesday",
thu: "thursday",
thur: "thursday",
thurs: "thursday",
fri: "friday",
sat: "saturday",
sun: "sunday"
}[c];
});
//change "comma" day intervals to "plus"
var daysInt = /(monday|tuesday|wednesday|thursday|friday|saturday|sunday),(monday|tuesday|wednesday|thursday|friday|saturday|sunday)/g;
while (daysInt.test(output)) {
output = output.replace(daysInt, "$1+$2");
}
//remove comma after days declarations
output = output.replace(/(monday|tuesday|wednesday|thursday|friday|saturday|sunday)\,/g, "$1");
//change intervals into using "plus"
output = output.replace(/(monday|tuesday|wednesday|thursday|friday|saturday|sunday)-(monday|tuesday|wednesday|thursday|friday|saturday|sunday)/g, function (c) {
var days = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"],
opt = [],
interval = c.split("-");
interval[0] = days.indexOf(interval[0]);
interval[1] = days.indexOf(interval[1]);
interval[0] -= interval[1] < interval[0] ? 7 : 0;
while (true) {
opt.push(days[interval[0] < 0 ? interval[0] + 7 : interval[0]]);
interval[0]++;
if (interval[0] > interval[1]) {
break;
}
}
opt = opt.join("+");
return opt;
});
//turn 12-hour format to 24-hour format
output = output.replace(/(\D)(\d)(?!\d)/g, "$10$2");
output = output.replace(/([^:])(\d\d)(am|pm)/g, "$1$2:00$3");
output = output.replace(/\d\d:\d\d(am|pm)/g, function (c) {
if (c.indexOf("pm") == -1) {
return c == "12:00am" ? "00:00" : c.replace("am", "");
} else {
c = c.replace("pm", "");
return c == "12:00" ? "12:00" : addZeros((+c.substr(0, 2) + 12)) + c.slice(2);
}
});
//split different times
output = output.split(/[,;]/);
return output;
}
答案 1 :(得分:1)
经过5个多小时,我完成了这个项目(在Derek的帮助下)。除了一个实例之外的所有实例都通在单个失败的项目上,结束时间显示错误。也许其他人可以看到错误。
以下是可能需要它的任何人的解决方案:
<强>预requisits:强>
修改/更新了DateJS来自:https://github.com/abritinthebay/datejs
<强>要点:强>
https://gist.github.com/bugs181/8819564
<强> JSBin:强>
http://jsbin.com/EXeyeZI/5/edit?html,js,console
<强>代码:强>
//var str = "monday-Thursday 9:00 PM - 12:00 PM, Tue 11:00 PM - 12:00 PM, Wednesday 10:00 PM - 12:00 PM"; // PASS
//var str = "Mon 6 am - 8 pm"; // PASS
//var str = "Mon-Fri 6 am - 8 pm"; // PASS
//var str = "Mon, Wed, Fri 9 pm - 12 pm"; // PASS
//var str = "Mon-Thu, Sun 11 am - 8 pm"; // PASS
//var str = "Monday 10:00 PM - 12:00 PM, Tuesday 11:00 PM - 11:30 PM, Wednesday 10:00 PM - 12:00 PM"; // PASS
//var str = "Mon-Fri 10am-10pm, Sat 10am-1am, Sun 9am-10am, some random text"; // PASS
//var str = "Mon-Fri 10am-10pm, don't break the days, Sat 10am-1am, Sun 9am-10am, some random text"; // PASS
//var str = "Mon-Fri 10am-10pm, !@#$%^&U* Sat 10am-1am, Sun 9am-10am, some random text"; // PASS
//var str = "mon 11:00am-12:00am, tue 11:00am-12:00am, wed 11:00am-02:00pm"; // PASS
//var str = "monday 11:00-21:00, tuesday 11:00-21:00, wednesday 11:00-21:00";// PASS
//var str = "mon 11:00am-8:00pm;tue 11:00am-8:30pm;wed 11:00am-8:30pm;thu 11:00am-8:30pm;"; // FAILED
var str = "monday-Thursday 10:00 PM - 11:00 PM, Tue 10:00 PM - 12:00 PM, Wednesday 10:00 PM - 12:00 PM"; // PASS
// Some useful variables.
var splitter = '$';
var short_days = new Array('mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun');
var long_days = new Array('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday');
var open_name_days = {}; // Place to store business hours object.
// Make text all lower case and remove white space.
var str = str.toLowerCase().replace(/\s/g, '');
// Match and replace any day abbreviations. Will match until non A-Z character.
var regex_days = /(mon|tue|wed|thu|fri|sat|sun).*?(?=[^a-z])/g;
var match;
while ((match = regex_days.exec(str)) !== null) {
var match_day = short_days.indexOf(match[1]); // Returns a regex short_day.
str = str.replace(match[0], long_days[match_day] + splitter); // Replace short_days with long_days in string.
}
// Replace any indicator for interval with + signs, which represent 'to'. Indicator will be assumed anything between start_day and end_day.
//str = str.replace(/-/g, '+');
// Split days by characters
var days = str.split(/[,;]/);
console.log(days);
console.log('');
// Loop through each day.
var len = days.length;
for (var i = 0; i < len; i++) {
if (!days[i]) continue;
var day = days[i].trim();
console.log('Day: ' + day);
// Find the start and end day. Will match until not A-Z character.
var regex_day = /(monday|tuesday|wednesday|thursday|friday|saturday|sunday).*?(?![a-z])/g;
// Something broke, so continue onto next day. This is likely caused by random text not containing a day.
if (!day.match(regex_day)) console.log('Something broke with regex_day');
if (!day.match(regex_day)) continue;
// Regex start_day and end_day from day.
var start_day = day.match(regex_day)[0];
var end_day = day.match(regex_day)[1];
end_day = ((end_day) ? end_day : start_day);
// Get indexes of start_day and end_day to be used later for days range.
var start_day_index = long_days.indexOf(start_day);
var end_day_index = long_days.indexOf(end_day);
console.log('start_day: [' + start_day_index + '] ' + start_day);
console.log('end_day: [' + end_day_index + '] ' + end_day);
// Detect times from day string.
var regex_time = /(\d\d:\d\d|\d{1,2})(am|pm)?/g;
// Regex time from this day string, fallback to string before split.
var time_match = day.match(regex_time);
// Something broke, this is likely caused by no time information. Attempt to retrieve it from string.
if (!time_match) {
time_match = str.match(regex_time);
if (!time_match) continue; // Unrecoverable at this point, continue onto next day.
}
var start_time = time_match[0];
var end_time = time_match[1];
// Parse time from Date.js.
start_time = new Date.parse(start_time).toString('h:mm tt');
end_time = new Date.parse(end_time).toString('h:mm tt');
console.log('start_time: ' + start_time);
console.log('end_time: ' + end_time);
console.log('');
// Loop through days range and output to object.
var len = short_days.length;
for (var b = 0; b < len; b++) {
if ((b >= start_day_index) && (b <= end_day_index)) {
var open_day_name_hour = short_days[b] + "_open";
var close_day_name_hour = short_days[b] + "_close";
open_name_days[open_day_name_hour] = start_time;
open_name_days[close_day_name_hour] = end_time;
}
}
}
console.log(open_name_days);