nic*_*ckf 1277 javascript regex
我想使用正则表达式匹配字符串的一部分,然后访问该带括号的子字符串:
var myString = "something format_abc"; // I want "abc"
var arr = /(?:^|\s)format_(.*?)(?:\s|$)/.exec(myString);
console.log(arr); // Prints: [" format_abc", "abc"] .. so far so good.
console.log(arr[1]); // Prints: undefined (???)
console.log(arr[0]); // Prints: format_undefined (!!!)
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
我发现有什么不对上述正则表达式代码:实际的字符串,我反对是这样的测试:
"date format_%A"
Run Code Online (Sandbox Code Playgroud)
报告"%A"未定义似乎是一种非常奇怪的行为,但它与此问题没有直接关系,所以我开了一个新的,为什么匹配的子字符串在JavaScript中返回"undefined"?.
问题是console.log它的参数就像一个printf语句,因为我正在记录的字符串("%A")有一个特殊的值,它试图找到下一个参数的值.
CMS*_*CMS 1585
您可以像这样访问捕获组:
var myString = "something format_abc";
var myRegexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
var match = myRegexp.exec(myString);
console.log(match[1]); // abcRun Code Online (Sandbox Code Playgroud)
如果有多个匹配,您可以迭代它们:
var myString = "something format_abc";
var myRegexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
match = myRegexp.exec(myString);
while (match != null) {
// matched text: match[0]
// match start: match.index
// capturing group n: match[n]
console.log(match[0])
match = myRegexp.exec(myString);
}Run Code Online (Sandbox Code Playgroud)
Mat*_*ens 179
这是一种方法,您可以使用它来获得每个匹配的第n个捕获组:
function getMatches(string, regex, index) {
index || (index = 1); // default to the first capturing group
var matches = [];
var match;
while (match = regex.exec(string)) {
matches.push(match[index]);
}
return matches;
}
// Example :
var myString = 'something format_abc something format_def something format_ghi';
var myRegEx = /(?:^|\s)format_(.*?)(?:\s|$)/g;
// Get an array containing the first capturing group for every match
var matches = getMatches(myString, myRegEx, 1);
// Log results
document.write(matches.length + ' matches found: ' + JSON.stringify(matches))
console.log(matches);Run Code Online (Sandbox Code Playgroud)
Phi*_*Lho 56
var myString = "something format_abc";
var arr = myString.match(/\bformat_(.*?)\b/);
console.log(arr[0] + " " + arr[1]);Run Code Online (Sandbox Code Playgroud)
这\b不完全是一回事.(它起作用--format_foo/,但不起作用format_a_b)但我想展示你的表达的替代品,这很好.当然,match通话很重要.
小智 30
关于上面的多匹配括号示例,我在找不到我想要的内容之后在这里寻找答案:
var matches = mystring.match(/(?:neededToMatchButNotWantedInResult)(matchWanted)/igm);
Run Code Online (Sandbox Code Playgroud)
在看了上面带有while和.push()的稍微复杂的函数调用之后,我突然意识到问题可以用mystring.replace()代替非常优雅(替换不是重点,甚至没有完成,CLEAN,第二个参数的内置递归函数调用选项是!):
var yourstring = 'something format_abc something format_def something format_ghi';
var matches = [];
yourstring.replace(/format_([^\s]+)/igm, function(m, p1){ matches.push(p1); } );
Run Code Online (Sandbox Code Playgroud)
在此之后,我认为我不会再使用.match()了.
Seb*_* H. 23
最后但并非最不重要的是,我发现一行代码对我来说很好(JS ES6):
let reg = /#([\S]+)/igm; // Get hashtags.
let string = 'mi alegría es total! ?\n#fiestasdefindeaño #PadreHijo #buenosmomentos #france #paris';
let matches = (string.match(reg) || []).map(e => e.replace(reg, '$1'));
console.log(matches);Run Code Online (Sandbox Code Playgroud)
这将返回:
['fiestasdefindeaño', 'PadreHijo', 'buenosmomentos', 'france', 'paris']
Run Code Online (Sandbox Code Playgroud)
Dan*_*ren 18
someString.match(regexPattern)./format_(.*?)/g,哪里(.*?)是匹配的组.)这些模式位于匹配的模式中.要访问匹配的组,在每个匹配的模式中,您需要一个函数或类似的东西来迭代匹配.正如许多其他答案所示,有很多方法可以做到这一点.大多数其他答案使用while循环来迭代所有匹配的模式,但我想我们都知道这种方法的潜在危险.有必要匹配一个new RegExp()而不仅仅是模式本身,只在评论中提到.这是因为该.exec()方法的行为类似于生成器函数 - 它在每次匹配时停止,但.lastIndex在下次.exec()调用时保持其继续.
下面是一个函数的一个例子searchString,它返回一个Array所有的匹配的模式,其中每一个match是一个Array与所有的含有匹配组.我没有使用while循环,而是提供了使用Array.prototype.map()函数和更for高效的方法的示例- 使用plain -loop.
这些性能较差,因为它们基本上实现了forEach-loop而不是更快的for-loop.
// Concise ES6/ES2015 syntax
const searchString =
(string, pattern) =>
string
.match(new RegExp(pattern.source, pattern.flags))
.map(match =>
new RegExp(pattern.source, pattern.flags)
.exec(match));
// Or if you will, with ES5 syntax
function searchString(string, pattern) {
return string
.match(new RegExp(pattern.source, pattern.flags))
.map(match =>
new RegExp(pattern.source, pattern.flags)
.exec(match));
}
let string = "something format_abc",
pattern = /(?:^|\s)format_(.*?)(?:\s|$)/;
let result = searchString(string, pattern);
// [[" format_abc", "abc"], null]
// The trailing `null` disappears if you add the `global` flag
Run Code Online (Sandbox Code Playgroud)
// Performant ES6/ES2015 syntax
const searchString = (string, pattern) => {
let result = [];
const matches = string.match(new RegExp(pattern.source, pattern.flags));
for (let i = 0; i < matches.length; i++) {
result.push(new RegExp(pattern.source, pattern.flags).exec(matches[i]));
}
return result;
};
// Same thing, but with ES5 syntax
function searchString(string, pattern) {
var result = [];
var matches = string.match(new RegExp(pattern.source, pattern.flags));
for (var i = 0; i < matches.length; i++) {
result.push(new RegExp(pattern.source, pattern.flags).exec(matches[i]));
}
return result;
}
let string = "something format_abc",
pattern = /(?:^|\s)format_(.*?)(?:\s|$)/;
let result = searchString(string, pattern);
// [[" format_abc", "abc"], null]
// The trailing `null` disappears if you add the `global` flag
Run Code Online (Sandbox Code Playgroud)
我还没有将这些替代方法与之前在其他答案中提到的方法进行比较,但我怀疑这种方法的性能较差,而且其他方法的安全性较低.
Jon*_*ski 17
你的语法可能不是最好的.FF/Gecko将RegExp定义为Function的扩展.
(FF2竟然typeof(/pattern/) == 'function')
这似乎是特定于FF - IE,Opera和Chrome都为它抛出异常.
相反,使用其他人先前提到的方法:RegExp#exec或String#match.
他们提供相同的结果:
var regex = /(?:^|\s)format_(.*?)(?:\s|$)/;
var input = "something format_abc";
regex(input); //=> [" format_abc", "abc"]
regex.exec(input); //=> [" format_abc", "abc"]
input.match(regex); //=> [" format_abc", "abc"]
Run Code Online (Sandbox Code Playgroud)
And*_*iro 16
无需调用该exec方法!您可以直接在字符串上使用"match"方法.只是不要忘记括号.
var str = "This is cool";
var matches = str.match(/(This is)( cool)$/);
console.log( JSON.stringify(matches) ); // will print ["This is cool","This is"," cool"] or something like that...
Run Code Online (Sandbox Code Playgroud)
位置0有一个包含所有结果的字符串.位置1具有由括号表示的第一个匹配,位置2具有在括号中隔离的第二个匹配.嵌套括号很棘手,所以要小心!
Wik*_*żew 16
String#matchAll (see the Stage 3 Draft / December 7, 2018 proposal), simplifies acccess to all groups in the match object (mind that Group 0 is the whole match, while further groups correspond to the capturing groups in the pattern):
With
matchAllavailable, you can avoid thewhileloop andexecwith/g... Instead, by usingmatchAll, you get back an iterator which you can use with the more convenientfor...of, array spread, orArray.from()constructs
This method yields a similar output to Regex.Matches in C#, re.finditer in Python, preg_match_all in PHP.
See a JS demo (tested in Google Chrome 73.0.3683.67 (official build), beta (64-bit)):
var myString = "key1:value1, key2-value2!!@key3=value3";
var matches = myString.matchAll(/(\w+)[:=-](\w+)/g);
console.log([...matches]); // All match with capturing group valuesRun Code Online (Sandbox Code Playgroud)
The console.log([...matches]) shows
You may also get match value or specific group values using
let matchData = "key1:value1, key2-value2!!@key3=value3".matchAll(/(\w+)[:=-](\w+)/g)
var matches = [...matchData]; // Note matchAll result is not re-iterable
console.log(Array.from(matches, m => m[0])); // All match (Group 0) values
// => [ "key1:value1", "key2-value2", "key3=value3" ]
console.log(Array.from(matches, m => m[1])); // All match (Group 1) values
// => [ "key1", "key2", "key3" ]Run Code Online (Sandbox Code Playgroud)
注意:请参阅浏览器兼容性详细信息。
只有在您有一对括号时才能使用的单线程:
while ( ( match = myRegex.exec( myStr ) ) && matches.push( match[1] ) ) {};
Run Code Online (Sandbox Code Playgroud)
使用你的代码:
console.log(arr[1]); // prints: abc
console.log(arr[0]); // prints: format_abc
Run Code Online (Sandbox Code Playgroud)
编辑:Safari 3,如果重要的话.
小智 6
function getMatches(string, regex, index) {
index || (index = 1); // default to the first capturing group
var matches = [];
var match;
while (match = regex.exec(string)) {
matches.push(match[index]);
}
return matches;
}
// Example :
var myString = 'Rs.200 is Debited to A/c ...2031 on 02-12-14 20:05:49 (Clear Bal Rs.66248.77) AT ATM. TollFree 1800223344 18001024455 (6am-10pm)';
var myRegEx = /clear bal.+?(\d+\.?\d{2})/gi;
// Get an array containing the first capturing group for every match
var matches = getMatches(myString, myRegEx, 1);
// Log results
document.write(matches.length + ' matches found: ' + JSON.stringify(matches))
console.log(matches);Run Code Online (Sandbox Code Playgroud)
function getMatches(string, regex, index) {
index || (index = 1); // default to the first capturing group
var matches = [];
var match;
while (match = regex.exec(string)) {
matches.push(match[index]);
}
return matches;
}
// Example :
var myString = 'something format_abc something format_def something format_ghi';
var myRegEx = /(?:^|\s)format_(.*?)(?:\s|$)/g;
// Get an array containing the first capturing group for every match
var matches = getMatches(myString, myRegEx, 1);
// Log results
document.write(matches.length + ' matches found: ' + JSON.stringify(matches))
console.log(matches);Run Code Online (Sandbox Code Playgroud)
使用es2018,您现在可以String.match()使用命名组,使您的正则表达式更加明确地说明其尝试执行的操作。
const url =
'/sf/ask/30274541/?some=parameter';
const regex = /(?<protocol>https?):\/\/(?<hostname>[\w-\.]*)\/(?<pathname>[\w-\./]+)\??(?<querystring>.*?)?$/;
const { groups: segments } = url.match(regex);
console.log(segments);
Run Code Online (Sandbox Code Playgroud)
你会得到像
{协议:“ https”,主机名:“ stackoverflow.com”,路径名:“ questions / 432493 / how-do-you-access-the-matched-groups-in-javascript-regular-expression”,查询字符串:“ some = parameter“}
即使我同意PhiLo 的观点,你的代码对我有用(Mac 上的 FF3) ,即正则表达式可能应该是:
/\bformat_(.*?)\b/
Run Code Online (Sandbox Code Playgroud)
(但是,当然,我不确定,因为我不知道正则表达式的上下文。)
| 归档时间: |
|
| 查看次数: |
719109 次 |
| 最近记录: |