Nginx配置使用详解

原文链接:https://blog.csdn.net/qq_46312987/article/details/118895520

1、常用命令
需要进入nginx的安装目录中的sbin目录(也可以配置环境变量,在任何目录都可以执行下面的命令),里面有一个nginx脚本文件

1、启动nginx
./nginx
2、关闭nginx
./nginx -s stop
3、重新加载nginx (nginx.conf)
./nginx -s reload
4、查看版本号
./nginx -v

2、Nginx配置文件(nginx.conf)
2.1概述
默认在Linux上安装的Nginx,配置文件在安装的nginx目录下的conf目录下,名字叫做nginx.conf

nginx.conf主要由三部分组成

全局块,
events块
http块
2.2配置文件结构

2.3真实配置文件概览

# 全局快

user nobody;

worker_processes 1;

error_log logs/error.log;

error_log logs/error.log notice;

error_log logs/error.log info;

pid logs/nginx.pid;


events块

events {
worker_connections 1024;
}

http块

http {
——————————————————————————# http全局块
include mime.types;
default_type application/octet-stream;

#log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
#                  '$status $body_bytes_sent "$http_referer" '
#                  '"$http_user_agent" "$http_x_forwarded_for"';

#access_log  logs/access.log  main;

sendfile        on;
#tcp_nopush     on;

#keepalive_timeout  0;
keepalive_timeout  65;

#gzip on;

server块

server {

server全局块

    listen       80;
    server_name  localhost;

    #charset koi8-r;

    #access_log  logs/host.access.log  main;

location块

    location / {
        root   html;
        index  index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}

}

可以配置多个server块

2.2全局块
就是配置文件从头开始到events块之间的内容,主要设置的是影响nginx服务器整体运行的配置指令比如worker_process, 值越大,可以支持的并发处理量也越多,但是还是和服务器的硬件相关

2.3events块
events 块涉及的指令主要影响 Nginx 服务器与用户的网络连接,常用的设置包括是否开启对多 work process下的网络连接进行序列化,是否允许同时接收多个网络连接,选取哪种事件驱动模型来处理连接请求,每个 word process 可以同时支持的最大连接数等。

上述例子就表示每个 work process 支持的最大连接数为 1024.
这部分的配置对 Nginx 的性能影响较大,在实际中应该灵活配置

2.4http块
包括http全局块,以及多个server块

2.4.1http全局块
http 全局块配置的指令包括文件引入、 MIME-TYPE 定义、日志自定义、连接超时时间、单链接请求数上限等。

2.4.2server块
这块和虚拟主机有密切关系,虚拟主机从用户角度看,和一台独立的硬件主机是完全一样的,该技术的产生是为了节省互联网服务器硬件成本。
每个 http 块可以包括多个 server 块,而每个 server 块就相当于一个虚拟主机
而每个 server 块也分为全局 server 块,以及可以同时包含多个 location 块。
2.4.2.1server全局块
最常见的配置是本虚拟机主机的监听配置和本虚拟主机的名称或 IP 配置。

#这一行表示这个server块监听的端口是80,只要有请求访问了80端口,此server块就处理请求

listen 80;
# 表示这个server块代表的虚拟主机的名字
server_name localhost;
1
2
3
4
2.4.2.2location块
一个 server 块可以配置多个 location 块。
主要作用是根据请求地址路径的匹配,匹配成功进行特定的处理
这块的主要作用是基于 Nginx 服务器接收到的请求字符串(例如 server_name/uri-string),对虚拟主机名称(也可以是 IP 别名)之外的字符串(例如 前面的 /uri-string)进行匹配,对特定的请求进行处理。地址定向、数据缓存和应答控制等功能,还有许多第三方模块的配置也在这里进行。

表示如果请求路径是/就是用这个location块进行处理

location / {
root html;
index index.html index.htm;
}
1
2
3
4
5
3、反向代理
3.1正向代理与反向代理概述
3.1.1正向代理
正向代理代理的是客户端,需要在客户端配置,我们访问的还是真实的服务器地址

3.1.2反向代理
反向代理代理的是服务器端,客户端不需要任何配置,客户端只需要将请求发送给反向代理服务器即可,代理服务器将请求分发给真实的服务器,获取数据后将数据转发给你。隐藏了真实服务器,有点像网关。

3.1.3区别与总结
正向代理与反向代理的区别

最根本的区别是代理的对象不同

正向代理代理的是客户端,需要为每一个客户端都做一个代理服务器,客户端访问的路径是目标服务器
反向代理代理的是真实服务器,客户端不需要做任何的配置,访问的路径是代理服务器,由代理服务器将请求转发到真实服务器
3.2配置
3.2.1应用一
实现效果访问http://192.168.80.102:80(Nginx首页),最终代理到http://192.168.80.102:8080(Tomcat首页)

首先启动一台Tomcat服务器(已经安装了Tomcat)

进入Tomcat的安装目录下的bin目录下,使用./startup.sh命令,启动Tomcat

在Nginx的配置文件中进行配置

1、新建一个server块,在server全局块中配置监听80端口

2、在location块中配置 / 路径请求代理到tomcat的地址

下面三个配置的含义就是 ,当访问Linux的http://192.168.80.102:80这个地址时,由于配置Nginx监听的是80端口,所以会进入这个server块进行处理,然后看你的访问路径,根据location块配置的不同路径进入对应的处理,由于配置了/请求,所以进入/的location处理,然后配置了proxy_pass,所以进行代理到指定的路径。

server {

监听端口80 即当访问服务器的端口是80时,进入这个server块处理

    listen       80;

server_name当配置了listen时不起作用

    server_name  localhost;

location后面代表访问路径 当是/ 请求时 代理到tomcat的地址

    location / {

使用 proxy_pass(固定写法)后面跟要代理服务器地址

        proxy_pass http://192.168.80.102:8080;
    }

}

经过测试,当输入http://192.168.80.102:80时,Nginx给我们代理到了Tomcat,所以显示了Tomcat的页面,即配置成功

3.2.2应用二
应用一访问的是/路径,给我们代理到指定的服务器

应用二实现:

让Nginx监听9001端口
我们实现当访问http://192.168.80.102:9001/edu(Nginx地址)时,nginx给我们代理到http://192.168.80.102:8081,
当访问http://192.168.80.102:9001/vod时,nginx给我们代理到http://192.168.80.102:8082
启动两个Tomcat服务器

端口分别是8081和8082,
在8001的服务器的webapps下创建一个edu目录,编写一个test.html
在8002的服务器的webapps下创建一个vod目录,编写一个test.html
由于虚拟机的ip是192.168.80.102,所以保证访问http://192.168.80.102:8081/edu/test.html和http://192.168.80.102:8082/vod/test.html 都可以成功访问

编写Nginx配置文件

server {

监听9001端口

    listen       9001;

进行路径匹配,匹配到edu代理到8081

    location ~/edu/ {
        proxy_pass http://192.168.80.102:8081;
    }

进行路径匹配,匹配到vod代理到8082

    location ~/vod/ {
        proxy_pass http://192.168.80.102:8082;
    }

}

经过测试,访问成功!!!

3.3location详解

3.4server_name作用及访问流程
客户端通过域名访问服务器时会将域名与被解析的ip一同放在请求中。当请求到了nginx中时。nginx会先去匹配ip,如果listen中没有找到对应的ip,就会通过域名进行匹配,匹配成功以后,再匹配端口。当这三步完成,就会找到对应的server的location对应的资源。

CSDN

4、负载均衡
4.1概述
简单来说就是使用分布式的场景,将原先的一台服务器做成一个集群,然后将请求分发到各个服务器上,但是,如何将请求每次转发到不同的服务器呢,Nginx就可以做到。原来我们都是直接访问服务器,现在我们可以使用Nginx进行反向代理,然后我们访问Nginx,由Nginx将我们的请求分发到不同的服务器上,以实现负载均衡

4.2配置
实现:

访问http://192.168.80.102:80/edu/test.html,Nginx将请求分配到8081和8082两台tomcat服务器上。

1、开启两台tomcat

分别在webapps下的edu下编写一个test.html,文件内容可以不一致,为了明显看到负载均衡的效果

2、配置文件

在http块中的全局块中配置

upstream固定写法 后面的myserver可以自定义

upstream myserver{
server 192.168.80.102:8081;
server 192.168.80.102:8082;
}

server配置

server {
  # 监听80端口
    listen 80;   
    #location块
    location / {

反向代理到上面的两台服务器 写上自定义的名称

    proxy_pass http://myserver;
    }
}


访问http://192.168.80.102:80/edu/test.html时,可以分发到8081和8082两台服务器,测试成功

4.3负载均衡规则
4.3.1轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除

4.3.2weight权重
weight 代表权重默认为 1,权重越高被分配的客户端越多

upstream myserver {
server 192.168.80.102:8081 weight=1 ;
server 192.168.80.102:8082 weight=2 ;
}
server {
listen 80;
location / {
proxy_pass http://myserver;
}

4.3.3ip_hash
每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决session问题

配置负载均衡的服务器和端口

upstream myserver {
server 192.168.80.102:8081;
server 192.168.80.102:8082;
ip_hash;
}
server {
listen 80;
location / {
proxy_pass http://myserver;
}
}

4.3.4fair
按后端服务器的响应时间来分配请求,响应时间短的优先分配。

配置负载均衡的服务器和端口

upstream myserver {
server 192.168.80.102:8081;
server 192.168.80.102:8082;
fair;
}
server {
listen 80;
location / {
proxy_pass http://myserver;
}
}

5、动静分离
5.1概述
将静态资源 css html js等和动态资源(jsp servlet)进行分开部署,我们可以将静态资源直接部署在专门的服务器上,也可以直接放在反向代理服务器上(Nginx)所在在的服务器上 然后动态资源还是部署在服务器上,如tomcat。
然后请求来的时候,静态资源从专门的静态资源服务器获取,动态资源还是转发到后端服务器上。

5.2配置
准备工作:在Linux的根目录下/的staticResource目录下创建两个文件夹,分别是www和image,在www目录下创建一个okc.html,在image目录下放一张ttt.jpg

实现效果,访问http://192.168.80.102:80/www/okc.html和http://192.168.80.102:80/image/ttt.img时可以成功访问资源

配置

server {
listen 80;
# 当访问路径带了www时,进入这个location处理,去/staticResource目录下对应的www目录 去找okc.html
# 即最终实现访问到这个路径
# http://192.168.80.102:80/staticResource/www/okc.html
location /www/{
root /staticResource/;
index index.html index.htm;
}
# 跟上面一样
location /image/{
root /staticResource/;
}
}
经过测试,成功访问

5.3root与alias区别与访问路径
alias 实际访问文件路径不会拼接URL中的路径
root 实际访问文件路径会拼接URL中的路径
示例如下:

alias

location ^~ /sta/ {
alias /usr/local/nginx/html/static/;
}

请求:http://test.com/sta/sta1.html
实际访问:/usr/local/nginx/html/static/sta1.html 文件
root

location ^~ /tea/ {
root /usr/local/nginx/html/;
}

请求:http://test.com/tea/tea1.html
实际访问:/usr/local/nginx/html/tea/tea1.html 文件
6、高可用集群
6.1概述
主备架构

作为备用服务器,当主服务器宕掉后,配置的备用服务器自动切换,
keepalived提供虚拟ip,对外我们访问的是虚拟ip,绑定了主备的ip

6.2配置
6.2.1环境搭建
开启两台虚拟机,都安装上nginx和keepalived

两台虚拟机的ip分别是 192.168.80.102 192.168.80.103

安装keepalived,直接使用yum安装

yum install -y keepalived

默认安装在/etc下,生成一个keepalived目录,里面有一个keepalived.conf文件,后面配置的主要就是这个配置文件

6.2.2配置

AI工具推荐

【【建议收藏】5个强到离谱的AI网站,总有一个你用得到!】 https://www.bilibili.com/video/BV1nX4y167gW/?share_source=copy_web&vd_source=7e55412f360a6ef7a503c2cdb428a5c2

这个视频给大家带来了5个超强AI网站,总有一个你用的到,建议收藏哦!

AI PPT生成:(1) gamma.app (2) design.meitu.com/ppt/?theme=dark (3) mindshow.fun 人声分离:lalal.ai 图像处理/视频处理:booltool.boolv.tech/home AI图像生成:rightbrain.art AI英文写作辅助:writingo.net收起

收到一个AI集合工具:https://ai.baiwen.net/

Mysql处理时间及字符串

1、mysql查询条件自动去除左边的0

处理办法:字符串+0,可以自动转换

2、计算时间差

SELECT DATEDIFF(‘2008-8-21,’2009-3-21’); 跟SqlServer 差不多

3、 在Mysql 数据库中存在两种字符串连接操作.具体操作如下 :

CONCAT(string1,string2,…) 说明 : string1,string2代表字符串,concat函数在连接字符串的时候,只要其中一个是NULL,那么将返回NULL 例1: 例2:

CONCAT_WS(separator,str1,str2,…) 说明 : string1,string2代表字符串,concat_ws 代表 concat with separator,第一个参数是其它参数的分隔符。分隔符的位置放在要连接的两个字符串之间。分隔符可以是一个字符串,也可以是其它参数。如果分隔符为 NULL,则结果为 NULL。函数会忽略任何分隔符参数后的 NULL 值。 举例1: mysql> select concat_ws(‘#’,’courseName=’,’NX’,null) AS nx_courseName;

MySQL中group_concat函数
完整的语法如下:
group_concat([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator ‘分隔符’])

基本查询

mysql> select * from stu1;
+——+——+
| id| name |
+——+——+
|1 | 10|
|1 | 20|
|1 | 20|
|2 | 20|
|3 | 200 |
|3 | 500 |
+——+——+
6 rows in set (0.00 sec)

以id分组,把name字段的值打印在一行,逗号分隔(默认)

mysql> select id,group_concat(name) from aa group by id;
+——+——————–+
| id| group_concat(name) |
+——+——————–+
|1 | 10,20,20|
|2 | 20 |
|3 | 200,500|
+——+——————–+
3 rows in set (0.00 sec)

以id分组,把name字段的值打印在一行,分号分隔

mysql> select id,group_concat(name separator ‘;’) from aa group by id;
+——+———————————-+
| id| group_concat(name separator ‘;’) |
+——+———————————-+
|1 | 10;20;20 |
|2 | 20|
|3 | 200;500 |
+——+———————————-+
3 rows in set (0.00 sec)

以id分组,把去冗余的name字段的值打印在一行,

逗号分隔

mysql> select id,group_concat(distinct name) from aa group by id;
+——+—————————–+
| id| group_concat(distinct name) |
+——+—————————–+
|1 | 10,20|
|2 | 20 |
|3 | 200,500 |
+——+—————————–+
3 rows in set (0.00 sec)

以id分组,把name字段的值打印在一行,逗号分隔,以name排倒序

mysql> select id,group_concat(name order by name desc) from aa group by id;
+——+—————————————+
| id| group_concat(name order by name desc) |
+——+—————————————+
|1 | 20,20,10 |
|2 | 20|
|3 | 500,200|
+——+—————————————+
3 rows in set (0.00 sec)

还有一个简单的连接方式为: ||

mysql> select * from student;
+—-+——+——-+———-+————+
| id | age | score | name | birth |
+—-+——+——-+———-+————+
| 1 | 23 | 78 | 李四 | 2017-10-10 |
| 2 | 24 | 78 | zhangsan | 2017-10-10 |
| 3 | 25 | 99 | 王五 | 2016-05-17 |
+—-+——+——-+———-+————+
3 rows in set (0.00 sec)

mysql> select id+999,name,name+99,name+’999′ from student;
+——–+———-+———+————+
| id+999 | name | name+99 | name+’999′ |
+——–+———-+———+————+
| 1000 | 李四 | 99 | 999 |
| 1001 | zhangsan | 99 | 999 |
| 1002 | 王五 | 99 | 999 |
+——–+———-+———+————+
3 rows in set, 6 warnings (0.00 sec)

css打印分页

一、打印方法:

一般打印web使用的是window.print()方法,当然也可使用vue-print

二、参数介绍:

@page中一般设置打印的页头页脚打印方向等,示例:

size:打印信息,打印纸张类型(A4)亦或控制打印方向,portrait: 纵向打印地, landscape: 横向。

@page{

margin: 4mm 14mm 4mm 4mm;

size:A4 landscape;

}

@media print 设置css中可以查看打印样式,示例:

media print {

}

可以将打印和页面的部分分离,需要注意的是需要打印的部分用“包含css样式再赋予函数,注意不是引号。然后抛出引入展示页面中,放在data的return {}下就行了。

三、分页:

分页的话使用的css样式一般是page-break-before与page-break-after这两个,对应的是打印前分页与打印后分页。

page-break-before 在元素前分页

page-break-after 在元素后分页

page-break-inside 元素内部分页

打印属性可以控制分页方向,可以设定4种设定值:auto、always、left和right。其中Auto是默认值,只有在有需要时,才需设定分页符号,以page-break-after示例:

page-break-after:auto; 默认值

page-break-after:always; 新分页在元素下方

page-break-after:left; 新分页在元素下方

page-break-after:right; 新分页在元素下方

注意:

1.分页的元素必须是个可展示的块级元素,为求保险最好加上display: block;

2.元素内分页我试过,不怎么管用,所有还是用page-break-after比较好,要循环中分页的建议加个判断,然后再设置分页,再添加新的table元素,在该table元素中复制这个循环同样加上判断展示分页后的内容

3.建议分页元素放在两个table元素之间,分页后的table元素设置margin-top,如果不起左右就在元素属性style上设置
————————————————
版权声明:本文为CSDN博主「qq_35491739」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_35491739/article/details/126279510

mysql计算正态分布、差异系数、离均差、离均差率

1、数据准备  建表 

drop table if exists score;
create table score(
    id int not null primary key auto_increment,
    score decimal(10,2) not null
);

  插入数据

insert into score (score) values (89.4);
insert into score (score) values (82.5);
insert into score (score) values (65);
insert into score (score) values (98);
insert into score (score) values (92);
insert into score (score) values (34);
insert into score (score) values (59);
insert into score (score) values (83);
insert into score (score) values (88);
insert into score (score) values (63);
insert into score (score) values (100);
insert into score (score) values (96);
insert into score (score) values (68);
insert into score (score) values (56);

注意:计算标准差最少需要两个值

2、计算正态分布

计算方法是:平均分-标准差(四个值:μ-2σ,μ-σ,μ+σ,μ+2σ)

select round(score_avg - score_bzc * 2, 2) zt1,
       round(score_avg - score_bzc, 2)     zt2,
       round(score_avg + score_bzc, 2)     zt3,
       round(score_avg + score_bzc * 2, 2) zt4
from (select avg(score) score_avg, stddev_samp(score) score_bzc
      from score
      where id in (1, 2)) as a;

3、计算差异系数

 计算方法是:标准差/平均分(σ/μ)

select round(score_bzc/score_avg,2) cyxs
from (select avg(score) score_avg, stddev_samp(score) score_bzc
      from score
      where id in (1,2)) as a;

4、计算离均差

计算方法是:单个值-平均值(x-μ)

select round(score - (avg(score) over ()), 2) ljc
from score
where id in (1, 2);

5、计算离均差率

计算方法是:离均差/平均值((x-μ)/μ)

select round((score - (avg(score) over ())) / (avg(score) over ()), 2) ljcl
from score
where id in (1, 2);

正则提取要选择题的选项

如下题匹配选项:

(1) 设集合 $A=[-1,2], B=\left{y \mid y=x^{2}, x \in A\right}$, 则 $A\cap B=$
A. $[1,4]$
B. $[1,2]$
C. $[-1,0]$
D. $[0,2]$

直接上代码:

    function getOption(str,from,to)
    {
        var r = 'var reg = /[\(]*'+from+'[:|:|、|.]{1}(.*?)[\s]?'+ to +'/';
        // console.log(r);
        eval(r);
        var arr = str.match(reg);
        console.log(arr);
        return arr[1].replace('<br/>','').replace('</p><p style=\"white-space: normal;\">','');
        //return str.match(reg)[1];
    }

格式化数据:

    function formatContent(content)
    {
        content = content.replace('\(A\)','A.').replace('\(B\)','B.').replace('\(C\)','C.').replace('\(D\)','D.').replace('\(E\)','E.').replace('\(F\)','F.'); 
        content = content.replace('<br/>','');
        content = content.replace('<br>','');
        content = content.replace('</p><p>'); 
        content = content.replace('<x','\\lt x');

        return content;    
    }

设置选项:

    function setChoiceItem()
    {
        var list =['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q'];
        var ue = UE.geEditor('question-content');
        var content = formatContent(ue.getContent());
        console.log(content);
        var str = content;

        //console.log(getOption(str,'A','B'));
        //console.log(getOption(str,'B','C'));
        //console.log(getOption(str,'C','D'));
        //console.log(getOption(str,'D','$'));

        //$('p.optionContent:eq(0)').html(getOption(content,'A','B'));
        //$('p.optionContent:eq(1)').html(getOption(content,'B','C'));
        //$('p.optionContent:eq(2)').html(getOption(content,'C','D'));
        //$('p.optionContent:eq(3)').html(getOption(content,'D','$'));
        
        var len = $('p.optionContent').length; 

        $('p.optionContent').each(function(index,e){

            console.log(list[index]);console.log(len);

            var start = list[index];
            var end = list[index+1];
            if(index == len-1) 
            {
                end='$';
            }

            $(this).html(getOption(content,start,end));

        });

    }

正则表达式“正向匹配和反向匹配”的妙用

相信大家在看正则表达式语法的时候都会遇到下面几种:正向肯定,正向否定,反向肯定,反向否定

1、(?=pattern)

正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串。

这是一个非获取匹配,该匹配不需要获取供以后使用。

例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,

但不能匹配“Windows3.1”中的“Windows”。

预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,

而不是从包含预查的字符之后开始。

2、(?!pattern)

正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串。

这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。

例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,

但不能匹配“Windows2000”中的“Windows”。

3、(?<=pattern)

反向肯定预查,与正向肯定预查类似,只是方向相反。

例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,

但不能匹配“3.1Windows”中的“Windows”。

4、(?<!pattern)

反向否定预查,与正向否定预查类似,只是方向相反。

例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,

但不能匹配“2000Windows”中的“Windows”。

我第一次看的时候就觉得很难理解,读了两遍好不容易理解了,但是一直用不上,直到工作需要……………

str = “111/;hkakdhaldladhl;gddhkshls;hhhh”
用 ; 切割字符串,要求切割结果是111/;hkakdhaldladhl gddhkshls hhhh,也就是第一个;前面有/,所以第一个;不分割,只分割后面的;

这其实就用到了反向否定,将python里面的split函数和正则表达式完美结合在一起,大家根据我的例子再去理解正(反)向否(肯)定匹配,肯定就更清晰了
python代码实现:

import re

str = “111/;hkakdhaldladhl;gddhkshls;hhhh”
str_list = re.split(r”(?<!\/);”,str)
print(str_list)
结果:

注:?<! 是反向否定的意思, \/ 是对 / 做了转义

为了能记得住,我总结了下面的规律,供参考~~

“肯定” 就是出现在?<! ?<= ?! ?= 后面那些字符,我们要匹配的字符串带这个才去匹配

“否定”就是出现在?<! ?<= ?! ?= 后面那些字符,我们要匹配的字符串不带这个才去匹配

“正反向”就是例子里面windows在 ?<! ?<= ?! ?= 以及后面字符的前面还是后面,windows在后是反向,在前是正向

记起来就是,四种都要带? 肯定的是= 否定的是! 如果是反向就加上<

Django根据已有的数据库来生成模型

日常开发中,我们有时会碰到数据库已经存在,而需要我们去生成模型的情况。这种情况下,我们需要:

Django中配置好数据库,确保连接得上这个已经存在的数据库
在cmd中运行命令,模型会生成在同一个文件中

 python manage.py inspectdb > models.py


修改模型
3.1 修改模型名,根据需求修改模型的名称
3.2 将不同的表放进其所属的app中
3.3 处理好表之间的外键关系(主要针对跨app的表,如果外键在同一个模型文件中,则可以跳过该步骤),在外键前加上app_name
3.4 让Django能够管理该模型并进行迁移:将Meta下的managed = False删除
3.5 当有多对多关系的表时,删除模型中的中间表,使用ManyToManyField来实现多对多,注意要设置中间表的名称让其与数据库中的中间表名一致
3.6 切记不要修改模型中的表名称,与数据库不一致的话会导致找不到表的错误
运行 python manage.py makemigrations
运行 python manage.py migrate –fake-initial
其中,在修改模型的时候,重点是需要分析好表与表之间的关系,只要能够弄清楚表与表之间的关系,那么修改模型会轻松很多