[英]JavaScript Regex to capture repeating part of decimal
Looking for the best way to take an arbitrary number with potentially repeating decimal part, and discover the repeating part (if present).寻找最佳方法来获取可能重复小数部分的任意数字,并发现重复部分(如果存在)。
Ultimately, I need to decorate the number with overline notation (either with css text-decoration or MathML mline), so I need to know the index of where the repetition begins also.最终,我需要用上划线符号(使用 css 文本装饰或 MathML mline)装饰数字,因此我还需要知道重复开始位置的索引。
So I need regex that will get me (or can be used in an algorithm to get) the following results:所以我需要正则表达式来获得(或可以在算法中使用以获得)以下结果:
1.333 // result: {"pattern": 3, index: 0}
1.5444 // result: {"pattern": 4, index: 1}
1.123123 // result: {"pattern": 123, index: 0}
1.5432121212 // result: {"pattern": 12, index: 4}
1.321 // result: null
1.44212 // result: null
Additional Example (from comments):附加示例(来自评论):
1.3333 // result: { "pattern": 3, index: 0}
You could try something like this: 你可以尝试这样的事情:
(\d+?)\1+$
http://regex101.com/r/eX8eC3/3 http://regex101.com/r/eX8eC3/3
It matched some number of digits and then uses a backreference to try and match the same set immediately afterwards 1 or more times. 它匹配了一些数字,然后使用反向引用尝试匹配相同的集合,然后立即进行1次或更多次。 It's anchored at the end of the string because otherwise it'll be tripped up by, for example:
它锚定在字符串的末尾,因为否则它会被绊倒,例如:
1.5432121212
It would see the 21
repeating instead of the 12
. 它会看到
21
重复而不是12
。
Adding ?
添加
?
to the first group to make it non-greedy should fix the problem with 1.3333
as raised by Louis. 第一组让它变得非贪婪应该解决路易斯提出的
1.3333
的问题。
function getRepetend(num) {
var m = (num+'').match(/\.(\d*?)(\d+?)\2+$/);
return m && {pattern: +m[2], index: m[1].length};
}
It works like this: 它的工作原理如下:
/\\.(\\d*?)(\\d+)\\2+$/
: /\\.(\\d*?)(\\d+)\\2+$/
:
\\.
matches the decimal dot. (\\d*?)
matches the digits between the decimal dot and the repetend, and captures the result into backreference number 1. (\\d*?)
匹配小数点和重复之间的数字,并将结果捕获到反向引号1。 (\\d+?)
matches the repetend, and captures it into backreference number 2. (\\d+?)
匹配重复,并将其捕获到反向引号2。 \\2+
matches repetitions of the repetend. \\2+
匹配重复的重复。 $
matches end of string. $
匹配字符串的结尾。 null
(ie there is no match), return null
. null
(即没有匹配),则返回null
。 You can use this regex with RexExp#exec
and use result.index
in the resulting object: 您可以将此正则表达式与
RexExp#exec
使用, result.index
在结果对象中使用result.index
:
var re = /(\d+)\1$/;
var s = '.5439876543212211211';
var result = re.exec( s );
console.log ( result.index );
//=> 14
console.log ( result[1] );
//=> 211
(.+)(?:\1)+$
Try this.See demo. 试试这个。看看演示。
http://regex101.com/r/uH3tP3/10 http://regex101.com/r/uH3tP3/10
The accepeted answer is OKish as per the given examples in the question are concerned.根据问题中给出的例子,接受的答案是好的。 However if one day you find yourself here what you probably need is exactly what the topic says.
但是,如果有一天您发现自己在这里,您可能需要的正是主题所说的内容。
/(\d+)\1+(?=\d*$)/g
Now this is not a silver bullet.现在这不是灵丹妙药。 It's helpful but won't protect you from vampires like
3.1941070707811985
which happens to have no repetend at all.它很有用,但不会保护你免受像
3.1941070707811985
这样的吸血鬼的伤害,它恰好根本没有重复。 In order to feel it you have to develop deeper mechanisms.为了感受它,你必须发展更深层次的机制。 However in most cases it's just fine in percieving the repend like in
但是在大多数情况下,像在
3.1941070707811985 // 07 which is wrong so prove it later 7.16666666810468 // 666 but reduce it to 6 later 3.00000000000001 // 000000 but reduce it to "" later 0.008928571428571428 // 285714 just fine, do nothing
It is not an easy task to find if the floating part of a decimal has repetends or not in this environment.在这种环境下查找小数的浮点部分是否重复不是一件容易的事。 Most possibly you need to do further processing on the given string and the result of the regex for futher reduction / decision.
很可能您需要对给定的字符串和正则表达式的结果进行进一步处理,以进一步减少/决定。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.