0

We can use javascript split method to split a string into an array of substrings. Example:

var timeformat="HH:MM:SS";
var timeformatarray=timeformat.split(":");

Is there a simple method to split a string if separator is not constant. Actually, I have to split timeformat that could come in any format like:

var timeformat="HH hr : MM min : SS sec";
var timeformat="HHhour:MMminute:SSsecond";
var timeformat="HHh MMm SSs";

Only constant would be HH, MM and SS. Timeformat is an option for the user to specify what is the format of the time that they want to display. "HH", "MM" and "SS" are constant text (Not numbers), these three are fixed constants that won't change. Only thing that could change is the suffix and the separator in the timeformat string as shown in examples above.

I want a method to split timeformat string into an array so that I can work on it. I want the result be:

timeformat[0] = "HH"
timeformat[1] = " hr : " <- with spaces (if any)
timeformat[2] = "MM"
timeformat[3] = " min : "
timeformat[4] = "SS"
timeformat[5] = " sec"

With this array, I will format the time and add respective suffix and separators. I tried various methods, using regex and looping through each character, but they were not efficient and straight. Thanks for the help in advance.

Solution: I was able to resolve the issue by creating a method that works on the formatstring using regex, split and arrays. I am sure there would be much better solution but I couldn't get any so here is my solution to the problem. I would thank Stephen C for the direction on regex.

function GetTimeFormatArray(timeformatstring){
        var timesuffixes = timeformatstring.split(/HH|MM|SS/);
        timesuffixes= $.grep(timesuffixes,function(n){
            return(n);
        });

        var pattern = timesuffixes.join('|');
        var timeprefixes = timeformatstring.split(new RegExp(pattern));
        timeprefixes = $.grep(timeprefixes,function(n){
            return(n);
        });

        var timeFormatArray = [];
        for(var i = 0; i < timesuffixes.length; i++){
            timeFormatArray.push(timeprefixes[i]);
            timeFormatArray.push(timesuffixes[i]);
        }
        return timeFormatArray;
    }
Sri Reddy
  • 6,832
  • 20
  • 70
  • 112
  • Identical question as http://stackoverflow.com/questions/650022/how-do-i-split-a-string-with-multiple-separators-in-javascript – saluce May 22 '12 at 00:03
  • It is not identical I guess.. in that they know the separators but in my case I don't know the separator. It could be any text within HH, MM and SS. Not sure if that makes sense. – Sri Reddy May 22 '12 at 00:22
  • So can the question be paraphrased as: **"I will have 3 numeric values, HH, SS from the user and I will need to reformat it to suit one of these 3 formats. How can I do it?"**? – inhan May 22 '12 at 11:45
  • No. Forget about the user. I have this `string` "HHhour:MMminute:SSsecond" and I need to create an array of strings having elements: "HH", "hour:", "MM", "minute:", "SS", "second". – Sri Reddy May 22 '12 at 13:12

3 Answers3

1

The function split() can take a regular expression as a delimiter. Here's a sample but I'm no expert in regex so this might not be optimized.

var test = 'HH hr : MM min : SS sec';

//split by ":" or space with optional leading and trailing space
console.log(test.split(/\s?[\s:]\s?/));​
//["HH", "hr", "MM", "min", "SS", "sec"]
Joseph
  • 117,725
  • 30
  • 181
  • 234
  • nice one but I want anything between HH and MM, MM and SS should be treated as separator. I don't know what the user will put as delimiter and format string? – Sri Reddy May 22 '12 at 00:09
1

If I was doing this in Java, I'd compose the delimiter regex from look-aheads and look-behinds. Unfortunately, Javascript regexes don't support look-behind.

I think you need to do this the hard way. Match the string with something like

    /(.*)HH(.*)MM(.*)SS(.*)/

and then index the array returned by the matcher. If the HH / MM / SS can appear in any order, etcetera you may need a more complicated regex like this:

    /(.*?)(?:(HH|MM|SS)(.*?))*/

This is using non-eager matching and a non-capturing group. You'd have to deal with cases like "HHMMSS" (i.e. no space between the "separators") and "SS one SS" (multiple instances of the same "delimiter"). Note also that this kind of pattern is rather dangerous, since a carefully crafted input can trigger huge amounts of back-tracking.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • I need to try this but I don't think I will ever have HH/MM/SS multiple times. Also, the order will be same but the string can have all or one or two of HH/MM/SS. Possible options are: "HH..MM..SS" or "HH..MM.." or MM..SS..". – Sri Reddy May 22 '12 at 13:31
  • Stephen, first regex seems to be working for storing the delimiter. I used `var arr = fs.split(/(.*)HH(.*)MM(.*)SS(.*)/);` There are two things I notice: 1. first and last elements in the array is blank 2. It only stores the delimiter in array, is there a way store HH | MM | SS also? or do I need another array to store it? – Sri Reddy May 22 '12 at 13:39
  • @kuul13 - please reread my answer. This regex is NOT designed to be used with `split`. Use `match`. – Stephen C May 22 '12 at 22:17
0
var rx = /^(\d{2})(.*?)(\d{2})(.*?)(\d{2})(.*?)$/
var timeformat = [
    "11 hr : 22 min : 33 sec",
    "11hour:22minute:33second",
    "11h 22m 33s"
];

for (var i = 0; i < timeformat.length; i++) {
    console.log(timeformat[i])
    try {
        for (var j = 0; j < timeformat[i].match(rx).length; j++) {
            console.log('\tmatch['+j+'] = ',timeformat[i].match(rx)[j]);
        }
    } catch(e) {}
}
inhan
  • 7,394
  • 2
  • 24
  • 35
  • Inhan, thanks for the response. I am not that good with regex, but how can I replace those numbers with "HH", "MM" and "SS". timeformat is just strings with no numeric values. User can pass any timeformat and I need to store it in array for further processing. – Sri Reddy May 22 '12 at 01:20
  • I don't quite get it. The timeformat array in my code was just an example for you to test the results in those 3 strings. The whole point was the **rx** regular expression there and use of the `.match()` method. Can you edit your question up and provide some more information? – inhan May 22 '12 at 01:48
  • I have edited the OQ. Hope it is little clear now. In my examples, "HH", "MM" and "SS" are constants text and is part of the timeformat. It can nver be numbers. This is timeformat, I will use the array to derive actual time. – Sri Reddy May 22 '12 at 02:52