最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to get rid of "undefined" in regexp result? - Stack Overflow

programmeradmin4浏览0评论

I do not understand why undefined appears in result. I use a question mark (\d+)?, it matches the previous element zero or one time:

// I want to match two cases with one regexp:
//   "GBP 5 per hour" and "GBP 5 per 10 hours"
//
"GBP 5 per hour".match(/([a-z]{3}) (\d+(?:\.\d+)?) per\s?(\d+)?\s?(hours?|days?|minutes?)/im)
["GBP 5 per hour", "GBP", "5", undefined, "hour"]  // actual result
["GBP 5 per hour", "GBP", "5", "hour"]  // the result I'd like to get

How to get rid of that undefined?

I do not understand why undefined appears in result. I use a question mark (\d+)?, it matches the previous element zero or one time:

// I want to match two cases with one regexp:
//   "GBP 5 per hour" and "GBP 5 per 10 hours"
//
"GBP 5 per hour".match(/([a-z]{3}) (\d+(?:\.\d+)?) per\s?(\d+)?\s?(hours?|days?|minutes?)/im)
["GBP 5 per hour", "GBP", "5", undefined, "hour"]  // actual result
["GBP 5 per hour", "GBP", "5", "hour"]  // the result I'd like to get

How to get rid of that undefined?

Share edited Jan 21, 2014 at 11:43 Green asked Jan 21, 2014 at 11:37 GreenGreen 30.9k62 gold badges163 silver badges253 bronze badges 1
  • Look at my example below for filtering an array values with a callback function. In this example, the callback tests on the type of the element passed and accepts rejects undefined elements. Hope it helps – php-dev Commented Jan 21, 2014 at 12:09
Add a ment  | 

5 Answers 5

Reset to default 3

The result will be the data (text) that is matched, if you are saying you want to match zero or one, and it matches zero then there is no data to return, and undefined is the result of that.

I would speculate that the design reason as to why the match is preserved is because it keeps the indexes consistent, so you can still access them as you would expect to. This way it enables you to effective test "was anything matched" by checking for undefined.

If you want to remove it from the array then you could use the filter function, for example:

arr = arr.filter(function(e){return e});

(Which I stole from here)

try

var x = ["GBP 5 per hour", "GBP", "5", undefined, "hour"];
var y = x.filter(Boolean);

as in Javascript any non-proper value is false that should help. Found it a few months ago written by Elad here

No simpler than

"GBP 5 per hour"
    .match(/([a-z]{3}) (\d+(?:\.\d+)?) per\s?(\d+)?\s?(hours?|days?|minutes?)/im)
    .filter(function(i){return typeof i != 'undefined'})

Since match will return an array, you can filter its elements with the filter method. The filter method can accept a callback (closure, function name as string, ...). Array elements are iterated and every element is passed to the callback function and is only accepted if the callback return value is equivalent to Boolean True

Hope it helps

The problematic part of your RegEx is:

per\s?(\d+)?\s?

Three possible solutions:

<script type="text/javascript">
//Quick & Dirty
var $text = "GBP 5 per hour";
var $arr = $text.match(/([a-z]{3}) (\d+(?:\.\d+)?) per ?(\d+)?\s?(hours?|days?|minutes?)/im);
console.log( $arr )
var $arrTmp = []
for( var $i = 0; $i < $arr.length; $i++ )
    if( typeof $arr[$i] != 'undefined' )
        $arrTmp.push( $arr[$i] )
$arr = $arrTmp;
console.log( $arr );

//Different approach
var $text = "GBP 5 per hour";
var $text1 = "GBP 5 per 10 hours";
var $regEx = /([a-z]{3}) (\d+(?:\.\d+)?) per(.*)(hours?|days?|minutes?)/im
var $arr = $text.match( $regEx );
var $arr1 = $text1.match( $regEx );

if( !isNaN( parseInt( $arr[3] ) ) )
    $arr[3] = parseInt( $arr[3] );
else
    $arr[3] = 1;
if( !isNaN( parseInt( $arr1[3] ) ) )
    $arr1[3] = parseInt( $arr1[3] );
else
    $arr1[3] = 1;


console.log( $arr1 );   
console.log( $arr );
</script>

undefined represents the place where the last digit you try to match should be (per\s?(\d+)) when the digit exists.

To be coherent in any case, you should keep it, and maybe handle it as if it was a 1.

If you prefer an empty string, you can try this one :

"GBP 5 per hour".match(/([a-z]{3}) (\d+(?:\.\d+)?) per\s?([\d]*)\s?(hours?|days?|minutes?)/im)

I don't know if it's possible to directly get an array without it (I mean without filtering the array).

发布评论

评论列表(0)

  1. 暂无评论