Joyber 发布的文章

要在一串数字中使用正则匹配一个11位的电话号码?要求数字是11位,且后面不能再有继续的数字,这个正则应该怎么写?

如果你希望 11位的电话号码 后面紧跟着可以跟其他字符(但不能是数字),可以调整正则表达式,确保电话号码后面没有数字。可以使用类似下面的正则:

/^\d{11}(?!\d).*$/

解释:

  • ^:表示字符串的开始。
  • \d{11}:表示精确匹配 11 位数字。
  • (?!\d):这是一个 负向前瞻(negative lookahead)。它的意思是:如果后面跟着数字,匹配会失败。确保在 11 位数字之后不会有数字。
  • .*:表示后面可以跟任意字符(除了换行符),但不会包括数字。
  • $:表示字符串的结束。

使用示例:

$pattern = '/^\d{11}(?!\d).*$/';
$phone_number = '13812345678abc';  // 示例电话

if (preg_match($pattern, $phone_number)) {
    echo "电话号码匹配成功!";
} else {
    echo "电话号码无效!";
}

说明:

  • 这个正则表达式会匹配 恰好 11 位数字,并且在 11 位数字之后,可以跟任意字符,但不能跟数字
  • 如果后面是数字,它就不会匹配。

举例:

  • 有效: 13812345678abc13812345678xyz12313812345678#@!
  • 无效: 13812345678123abc123(后面跟着数字),1381234567(不足 11 位)

在 JavaScript 中,?. 是一种可选链操作符(Optional chaining operator),它可以简化访问可能为null或undefined的属性或方法的代码书写,避免因为对象链中某个属性或方法不存在而导致的错误。?. 的使用方式如下:

1. 访问属性

// 普通访问方式
const name = user.profile.name; // 如果 user 或 profile 为 null 或 undefined,将会导致错误

// 使用可选链操作符
const name = user?.profile?.name; // 如果 user 或 profile 为 null 或 undefined,name 将会取到 undefined

2. 调用方法

// 普通调用方法方式
const result = app.getData(); // 如果 app 为 null 或 undefined,将会导致错误

// 使用可选链操作符
const result = app?.getData(); // 如果 app 为 null 或 undefined,result 将会取到 undefined

3. 数组访问

const arr = [1, 2, 3];
const value = arr?.[0]; // 如果 arr 为 null 或 undefined,value 将会取到 undefined

4. 函数调用

function sayHello() {
  console.log('Hello, world!')
}

const func = sayHello?.(); // 如果 sayHello 为 null 或 undefined,调用将会被忽略

可选链操作符 ?. 使得我们可以更加安全和简洁地访问对象的属性和方法,避免代码中大量的空值检查,提高代码的可读性和健壮性。需要注意的是,?. 操作符在一些较老版本的 JavaScript 环境可能不被支持,因此在使用时需要注意环境的兼容性。

兼容性情况

可选链操作符 ?. 在 JavaScript 中的兼容性随着不同 JavaScript 引擎和浏览器的更新而有所变化。以下是可选链操作符的兼容性情况:

1. Node.js

  • 可选链操作符从 Node.js 14 版本开始得到支持,但需要在 JavaScript 文件中指定 ECMASCript版本 支持。
  • 可以通过在项目中的 .eslintrc 文件中设置 ecmaVersion: 2020 来指定支持 ECMAScript 2020。

2. 现代浏览器

  • Chrome、Firefox、Edge 等现代浏览器在较新的版本中已经支持可选链操作符。
  • 可以在 Can I Use 网站上查看各个浏览器对可选链操作符的支持情况。

3. Babel 转译

  • 如果项目需要兼容性,可以使用 Babel 将项目中的可选链操作符转译为普通的 JavaScript 代码,以确保在旧版 JavaScript 引擎中的兼容性。
  • 可以在 Babel 的官方文档中找到相关的插件和配置信息。

4. Polyfill

  • 也可以使用相应的 Polyfill 库来实现可选链操作符在旧版 JavaScript 环境下的同等效果。
  • 一些流行的 JavaScript Polyfill 库(如 core-js)提供了可选链操作符的支持。

总的来说,随着 JavaScript 标准的不断发展和现代浏览器的更新,可选链操作符在很多环境中都得到了良好的支持。但在项目中应根据实际情况考虑目标用户群体的环境兼容性,选择合适的方案来处理可选链操作符的兼容性问题。

在 MySQL 中,DATETIME 类型用于存储日期和时间的组合值。DATETIME 类型支持各种日期和时间计算,可以进行日期加减、时间比较、格式转换等操作。以下是 DATETIME 类型支持的一些常见计算:

1. 日期加减

  • 加法操作:可以通过 DATE_ADD() 函数将指定的天数、月数、年数等加到 DATETIME 值上。

    SELECT DATE_ADD('2022-12-31 12:00:00', INTERVAL 1 DAY); -- 加一天
  • 减法操作:可以通过 DATE_SUB() 函数将指定的天数、月数、年数等从 DATETIME 值中减去。

    SELECT DATE_SUB('2022-12-31 12:00:00', INTERVAL 1 MONTH); -- 减一个月

2. 日期比较

  • 可以使用比较操作符(如 <, >, =)对 DATETIME 值进行比较,以判断它们之间的顺序关系。

    SELECT * FROM table WHERE date_column > '2022-01-01 00:00:00';

3. 日期格式转换

  • 可以使用 DATE_FORMAT() 函数将 DATETIME 值转换为指定格式的字符串,便于显示或比较。

    SELECT DATE_FORMAT('2022-12-31 12:00:00', '%Y-%m-%d'); -- 格式化日期

4. 日期函数

  • 可以使用各种日期函数(如 YEAR(), MONTH(), DAY(), HOUR(), MINUTE(), SECOND() 等)提取 DATETIME 值的部分内容。

    SELECT YEAR('2022-12-31 12:00:00'); -- 提取年份

5. 日期范围查询

  • 可以使用 BETWEEN 操作符来查询某个日期范围内的数据。

    SELECT * FROM table WHERE date_column BETWEEN '2022-01-01 00:00:00' AND '2022-12-31 23:59:59';

6. 日期加减操作

  • 可以通过将日期字段加减相应的天数、月数、年数,来实现日期的调整。

    UPDATE table SET date_column = date_column + INTERVAL 1 HOUR;

总结:

DATETIME 类型支持丰富的日期和时间计算操作,包括日期加减、日期比较、日期格式转换、日期函数、日期范围查询等,为处理日期和时间数据提供了便利和灵活性。通过合理运用这些计算能力,可以满足各种对日期和时间数据的需求。

在 MySQL 中,UNIX_TIMESTAMPFROM_UNIXTIME 函数用于处理时间戳和日期之间的转换。它们都基于 Unix 时间戳,通常代表自 1970年1月1日 00:00:00 UTC 起的秒数。

1. UNIX_TIMESTAMPFROM_UNIXTIME 支持的最大时间戳

  • UNIX_TIMESTAMP:返回当前时间或指定时间的 Unix 时间戳。这个时间戳是一个 32 位的整数,表示从 1970 年 1 月 1 日 00:00:00 UTC 开始经过的秒数。
  • FROM_UNIXTIME:根据指定的 Unix 时间戳返回日期和时间。它能够将一个 Unix 时间戳转换为可读的日期和时间。

MySQL 的 Unix 时间戳是一个有符号的 32 位整数,因此它的最大值是 2147483647(即 2^31 - 1)。这个时间戳对应的日期是 2038年1月19日 03:14:07 UTC。这个时间点通常被称为“2038年问题”或“Y2K38问题”。

因此:

  • 对于 32 位有符号整数,支持的最大 Unix 时间戳是 2147483647,对应的时间为 2038年1月19日 03:14:07 UTC

2. 如何解决这个问题

2038年问题 是指,当时间戳超出 32 位整数的范围时,程序将无法正确处理时间。解决此问题的方式有几种:

1. 使用 64 位系统

  • 在 64 位操作系统和数据库中,Unix 时间戳通常会使用 64 位整数(大约能表示从公元前 292亿年到公元292亿年之间的时间),因此不会遇到 2038年问题。
  • MySQL 支持使用 64 位时间戳,但需要确保数据库和相关的应用程序在支持 64 位整数的环境中运行。

2. 升级 MySQL 版本

  • 新版本的 MySQL 默认可以处理更大的时间戳,具体支持的最大时间戳取决于 MySQL 的版本和配置。例如,MySQL 5.6 及以上版本支持 DATETIME 类型的 64 位时间戳。

3. 使用 DATETIMETIMESTAMP 类型

  • 使用 DATETIMETIMESTAMP 类型来存储时间,而不是直接依赖 Unix 时间戳。DATETIME 可以存储更大的范围(从 1000-01-019999-12-31),不受 32 位时间戳的限制。

例如:

SELECT UNIX_TIMESTAMP('2038-01-19 03:14:07');

如果使用 DATETIME 类型,则可以直接使用日期时间格式进行存储和计算,避免 Unix 时间戳限制的问题。

总结:

  • UNIX_TIMESTAMPFROM_UNIXTIME 函数的最大时间戳值为 2147483647,对应 2038年1月19日 03:14:07 UTC
  • 解决 2038年问题的方式包括使用 64 位系统、使用更高版本的 MySQL,或使用 DATETIME 类型存储日期。

在 NGINX 中,sub_filtersub_filter_once 是用于内容替换的指令,通常与 ngx_http_sub_module 模块一起使用。这个模块允许你在响应中进行字符串替换,以便动态修改页面内容。

1. sub_filter

sub_filter 用于在 NGINX 处理 HTTP 响应时执行文本替换。它允许你指定要替换的原始文本和替换后的新文本。

语法:

sub_filter <pattern> <replacement>;
  • <pattern>:需要替换的文本模式(可以是正则表达式,也可以是普通字符串)。
  • <replacement>:用来替换 <pattern> 的文本。

例子:

假设你希望将响应中的所有 http://old-url.com 替换为 https://new-url.com,可以这样配置:

sub_filter 'http://old-url.com' 'https://new-url.com';

2. sub_filter_once

sub_filter_once 用来指定是否只进行 一次替换,即只替换响应中的第一个匹配项。默认情况下,sub_filter 会替换所有匹配的文本,但 sub_filter_once 可以让你控制是否只替换第一次出现的匹配内容。

语法:

sub_filter_once on|off;
  • on:表示只进行一次替换,默认是 off,即替换所有匹配的文本。
  • off:表示对所有匹配项进行替换。

例子:

假设你只想替换响应中第一次出现的 http://old-url.com,可以这样配置:

sub_filter_once on;
sub_filter 'http://old-url.com' 'https://new-url.com';

总结:

  • sub_filter:在 NGINX 响应中进行文本替换,将所有匹配的文本替换为指定的文本。
  • sub_filter_once:控制替换是否仅发生一次(默认情况下,替换所有匹配项)。如果设置为 on,只会替换第一次出现的匹配文本。