关于在 Javascript 上的字符之间分隔子字符串的最佳实践

Best practice regarding separating a substring between characters on Javascript

注意:我标记了 google-app-script,因为那是我工作的地方,我不知道是否有一些不同的术语对每个人在回答问题时都很重要。

目前,要找到出现在固定字符'FT '')'之间的分数(在下面的例子中是0-0),我是这样做的:

var text = 'So its (just 1-2) amazing (FT 0-0) its ours final score';
var length = text.length;
var find_str_ft = 'FT ';
var find_str_ft_length = find_str_ft.length;
var position = text.indexOf(find_str_ft);
var text_right = text.substring(position + find_str_ft_length, length);

var find_str_close_bar = ')';
var position_close_bar = text_right.indexOf(find_str_close_bar);
var text_left_close_bar = text_right.substring(0, position_close_bar);
Logger.log(text_left_close_bar);

日志:

0-0

我知道这是一种过时的方法,我想知道是否有更高级和更正确的选项可供使用,即使它不需要那么多步骤 and/or 这么多为此的代码行。

我敢肯定它不是绝对最好的,我可以想象它不切实际的地方,但我喜欢的适用于许多用例的通用解决方案如下:

var str = 'BeginingoflongstringFToranystringScoreorwhateverwewant)oranystringEndoflongstring';
var first_filter = 'FToranystring';
var second_filter = ')oranystring';
var desired_string = str.slice(
  str.indexOf(first_filter) + first_filter.length,
  str.indexOf(second_filter),
);
console.log(desired_string);

根据您的具体数据,我们使用 lastIndexOf 而不是 indexOf 进行更改,因为它是您字符串中的 non-unique 短语。一般情况下,最好只搜索两个唯一字符串之间的字符串:

var str = 'So its (just 1-2) amazing (FT 0-0) its ours final score';
var first_filter = 'FT';
var second_filter = ')';
var desired_string = str.slice(
  str.indexOf(first_filter) + first_filter.length,
  str.lastIndexOf(second_filter),
);
console.log(desired_string);

或者,在这种情况下,您可以使用 ") i":

而不是只使用结束符 ")"

var str = 'So its (just 1-2) amazing (FT 0-0) its ours final score';
var first_filter = 'FT';
var second_filter = ') i';
var desired_string = str.slice(
  str.indexOf(first_filter) + first_filter.length,
  str.indexOf(second_filter),
);
console.log(desired_string);

无论如何,它需要完全了解您的输入字符串,所以不太理想。

正则表达式将使这变得非常简单:

let text = 'So its (just 1-2) amazing (FT 0-0) its ours final score';
let match = text.match(/\(FT\s+([^)]+)\)/);
let result = match[1];

您想匹配左侧:

\(FT\s+

表示匹配 (FT 和 1 个或多个空白字符。

那么你要匹配你想要的实际数据:

([^)]+)

这会匹配并捕获任何不是 )(我们的匹配结束)并且出现不止一次的字符。

然后你匹配右边。

\)

字面意思就是 ) 字符。

与正则表达式匹配

function lfunko() {
  let s = "So its (just 1-2) amazing (FT 0-0) its ours final score";
  let m = s.match(/(?<=just )([^\)]+)|(?<=FT )([^\)]+)/g);
  Logger.log('First: %s Second: %s', m[0],m[1]);
}

Execution log
3:26:04 PM  Notice  Execution started
3:26:05 PM  Info    First: 1-2 Second: 0-0
3:26:05 PM  Notice  Execution completed

利用组合在一起的两个正面外观。

如果您想在这样的比赛中看到一些真正的专业知识,只需添加一个 regex 标签,您就会看到一些真正的正则表达式大师。

为您添加了 Regex 标签。在做出最终选择之前等待@Wiktor Stribiżew 回答。

还有一个很好的衡量标准...

const text = 'So its (just 1-2) amazing (FT 7-10) its ours final score';
const regexScore = /FT\s+\d+-\d+/ig;
const regexDigits = /\d+/g
const found = text.match(regexScore);
const score = found[0].match(regexDigits);

console.log(found);
console.log(score);

您可以使用捕获组并将数字与连字符匹配,其中捕获组 1 值在示例代码中由 m[1] 表示:

\(FT\s+(\d+-\d+)\)

说明

  • \( 匹配 (
  • FT\s+ 匹配 FT 和 1+ 个空白字符
  • (\d+-\d+) 捕获第1组,匹配1+位- 1+位
  • \) 匹配 )

const text = 'So its (just 1-2) amazing (FT 0-0) its ours final score';
const m = text.match(/\(FT\s+(\d+-\d+)\)/);
if (m) {
  console.log(m[1]);
}

如果使用 /g 标志可以出现更多次:

const text = 'So its (just 1-2) amazing (FT 0-0) its ours final score, and not (FT 1-1)';
console.log(Array.from(text.matchAll(/\(FT\s+(\d+-\d+)\)/g), m => m[1]));

替代方法:

除了使用 regex:

外,您还可以使用 split method with substr / substring

脚本

function test() { //E.g. you have mustiple instances of "FT"
  var text = 'So its amazing (FT3-0 ) (just 1-2)  amazing (FT  0-0) its ours final score (FT 1-1  )';
  var match = text.split("FT");
  for(var i in match){
    if(i != 0){ //skip index 0 as it doesn't contain the score after every "FT" instance.
      Logger.log(match[i].trim().substr(0, 3)); //used trim to remove all white spaces before the substr method
    }
  }
}

结果