【问题标题】:Get part of substring before character在字符之前获取部分子字符串
【发布时间】:2021-02-03 04:57:57
【问题描述】:

我有一个网址,像这样:

https://www.example.com/exampletitle21sep11oct2020/index.html

我需要的部分是在最后一个和倒数第二个“/”字符之间。但我不需要整个部分,我特别需要最后一个“/”字符之前的最后一个日期。如您所见,有两个日期紧挨着,它们之间没有分隔符,因此很难使用substringindexOf 方法。更难的是,第一个日期只包含日期和月份,而最后一个日期包含整个日期。

我有什么方法可以从这个网址中提取最后一个“/”字符之前的最后一个日期吗?

【问题讨论】:

  • String.prototype.split()?
  • 我可以使用 '/' 字符轻松拆分它,但是拆分后,我如何获得最后一个日期?如何在两个日期之间进行拆分?
  • 您需要根据您设置的指南进行某种解析。但是,如果您可以更改后端的路径以确保开始日期和结束日期之间存在某种分离,那就更好了。
  • 我同意更改 url 并添加某种分隔会更好,但是 url 来自我们的客户,他们拒绝更改。所以现在我们必须找到一种肮脏的方式来按原样使用 url。
  • 你需要来自网址的第二个日期11oct2020吗?

标签: javascript string react-native substring indexof


【解决方案1】:

使用正则表达式,您可以获得第二个日期,如下所示:

const regex = /\/(?:.*?(\d{1,2}\w{3}\d{0,4}))\/.*?$/;

const [, date] = regex.exec("https://www.example.com/exampletitle21sep11oct2020/index.html");
console.log({ date })

const regex = /\/(?:.*?(\d{1,2}\w{3}\d{0,4}))\/.*?$/;

const [, date] = regex.exec("https://www.example.com/exampletitle21sep9oct2020/index.html");
console.log({ date });
console.log(regex.exec("https://www.example.com/exampletitle21sep9oct/index.html")[1])

【讨论】:

  • 谢谢,这行得通。但是当我使用例如 9sep9oct2020 时它确实会崩溃。我想那会打破这种模式。我可以将它包装在 try / catch 中以防止崩溃吗?
  • 更新了答案以支持个位数的日子。
  • 似乎有时也缺少年份(2020)。请问我该如何支持这种情况?
  • 我试过/\/(?:.*?(\d{1,2}\w{3}\d{0,4}))\/.*?$/,但它不起作用。
  • 更新了答案,请查看sn-p
【解决方案2】:

您可以找到并解析包含以下模式的路径:

^         Line start
.+        One or more of anything
(\d{2})   2-digit date
(\w{3})   3-letter month (lowercase)
(\d{2})   2-digit date
(\w{3})   3-letter month (lowercase)
(\d{4})   4-digit year
$         Line end

示例

我使用moment 来处理日期解析。

const expression = /^.+(\d{2})(\w{3})(\d{2})(\w{3})(\d{4})$/;
const format = 'DD MMM YYYY';
const toTitleCase = (str) => str.charAt(0).toUpperCase() + str.slice(1);

const parseDates = (path) => {
  const url    = new URL(path),
        tokens = url.pathname.split('/'),
        found  = tokens.find(token => token.match(expression));
  if (!found) return null;
  const [
    , startDate, startMonth, endDate, endMonth, year
  ] = found.match(expression);
  return {
    start : moment(`${startDate} ${toTitleCase(startMonth)} ${year}`, format),
    end   : moment(`${endDate} ${toTitleCase(endMonth)} ${year}`, format)
  };
};

const dates = parseDates('https://www.example.com/exampletitle21sep11oct2020/index.html');

console.log(dates);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>

【讨论】:

  • 非常令人印象深刻,谢谢。我一直在尝试使用它,但它给了我一个错误,说“未实现”。我导入了时刻,所以我知道这不是错误......你认为我做错了什么?
  • @instanceof 什么没有实现?
  • 我不确定,这是它给出的关于错误的唯一信息,除了堆栈跟踪。
  • @instanceof 只需发布堆栈跟踪的前几行。作为一名开发人员,关注这一点非常重要。
  • 错误:未实现 此错误位于:在 SpecialsScreen(由 ConnectFunction 创建)中 ConnectFunction(在 SceneView.js:9)中 在 SceneView(在 StackViewLayout.tsx:900)中 在 RCTView(在 createAnimatedComponent .js:151)在 AnimatedComponent 中(在 StackViewCard.tsx:106)...顺便说一下,我正在 React Native 中开发
【解决方案3】:

试试这个更新

const url = "https://www.example.com/exampletitle21sep11oct2020/index.html";
const urlData = url.split('/');
const datePart = urlData[urlData.length-2];
const res = datePart.slice(-9); <-- this will give you "11oct2020" -->

【讨论】:

  • 谢谢,但是我该如何区分“sep”和“11oct2020”呢?我只需要“11oct2020”。
  • 我已经更新了我的答案。这会给你 11oct2020
【解决方案4】:

只需一个正则表达式,一切都会变得简单得多:

var url = 'https://www.example.com/exampletitle21sep11oct2020/index.html'

var res = url.match( /.*?(\d+[a-z]+\d{4})\/.*?$/i );
// res === [ "https://www.example.com/exampletitle21sep11oct2020/index.html", "11oct2020" ]
var endDate = res[1];
// endDate === "11oct2020"

或(但“exampletitle”不能以数字结尾):

var res = url.match( /.*?(\d+[a-z]+)(\d+[a-z]+)(\d{4})\/.*?$/i );
// [ "https://www.example.com/exampletitle21sep11oct2020/index.html", "21sep", "11oct", "2020" ]

或:

var res = url.match( /.*?(\d+)([a-z]+)(\d+)([a-z]+)(\d{4})\/.*?$/i );
// [ "https://www.example.com/exampletitle21sep11oct2020/index.html", "21", "sep", "11", "oct", "2020" ]

但是,如果您知道日期总是两位数(总是“01”,而不是“1”),那么“exampletitle”可以是任何字符串:

var res = url.match( /.*?(\d{2}[a-z]+\d{4})\/.*?$/i );
var res = url.match( /.*?(\d{2}[a-z]+)(\d+[a-z]+)(\d{4})\/.*?$/i );
var res = url.match( /.*?(\d{2})([a-z]+)(\d+)([a-z]+)(\d{4})\/.*?$/i );

【讨论】:

  • 所以即使使用日期,例如 9sep9oct2020 或 9sep19oct2020,这也会起作用?
  • 是的。但在这种情况下,“exampletitle”子字符串的末尾不能包含数字。但如果日期格式为 00aaa(2 位),最好使用url.match( /.*?(\d{2}[a-z]+\d{4})\/.*?$/i ),它不限制“exampletitle”子串(结尾可以包含数字)。
  • 别忘了检查resnull 的值(match() 返回null,如果与模板不一致 - 即如果 url 有其他格式)。例如:endDate = res ? res[1] : null;endDate = (res||[])[1];
猜你喜欢
  • 1970-01-01
  • 2019-10-05
  • 2021-11-19
  • 1970-01-01
  • 2016-09-05
  • 2018-04-14
  • 2019-06-16
  • 2013-02-07
  • 2020-02-29
相关资源
最近更新 更多