调用MYSQL 删除HTML代码并限制长度

调用MYSQL 删除HTML代码并限制长度,第1张

public static function filter_newslink($aid){

$content = mod_news :: get_newscont($aid)

//先过滤图片的外链 非贪婪匹配 普通正则用?,PHP用/U转变是否贪婪

$content = preg_replace('/<a([^>]*)>(<img[^>]*>)<\/a>/iU', '$2', $content)

//再过滤文字的外链<a title="" href="">文字</a>为文字

$content = preg_replace('/<a([^>]*)>([^<]*)<\/a>/iU', '$2', $content)

$data = array('news_id' =>$aid, "content" =>$content)

$status = mod_news :: update_newscontent($data)

return $status

}

贪婪匹配(Greedy)是最大匹配,例如对于html字符串

nowamagic.net is a <b>good</b>website to <b>learn</b>IT <b>skills</c>.

通过正则<b>.*</b>默认匹配的结果为:

<b>good</b>website to <b>learn</b>

但许多情况下我们想要的其实是<b>good</b>和 <b>learn</b>两个匹配

解决的办法,就是上面说到的非贪婪匹配,即惰性匹配,它的语法如下表所示:

贪婪匹配惰性匹配匹配描述

???匹配 0 个或 1 个

++?匹配 1 个或多个

**?匹配 0 个或多个

{n}{n}?匹配 n 个

{n,m}{n,m}?匹配 n 个或 m 个

{n,}{n,}?匹配 n 个或多个

上述例子使用非贪婪匹配<b>.*?</b>得到的结果为两个匹配,这次符合我们的需要了。

PHP正则表达式模式修正符:

i 正则内容在匹配时候不区分大小写(默认是区分的)

m 在匹配首内容或者尾内容时候采用多行识别匹配

S 将转义回车取消是为单行匹配如. 匹配的时候

x 忽略正则中的空白

A 强制从头开始匹配

D 强制$匹配尾部无任何内容 \n

U 禁止贪婪匹配 只跟踪到最近的一个匹配符并结束,常用在采集程序上的正则表达式

这里是一个正则匹配的在线匹配测试工具:http://tool.oschina.net/regex

替换文章的关键词标签可以使用MySQL导出后加工再导入数据库,也可以使用存储过程实现。这个的存储过程简单写一下:

[sql] view plain copy

delimiter //

create procedure replaceAllTag()

begin

declare i INT

while i <=20 do

select replace(tag,",i,",",COSTi,") FROM `TBL_CMS_NEWS_bak` WHERE `col_id_related`=661 and tag like "%,i,%"

set i=i+1

end while

end //

delimiter

在PhpMyAdmin中,drop procedure replaceAllTag 需要单独执行,否则会报错。存储过程的语法请参照以下实例:

[sql] view plain copy

delimiter //

CREATE PROCEDURE `dadada` ()

BEGIN

DECLARE x INT

DECLARE str VARCHAR(255)

SET x = 1

SET str = ''

WHILE x <= 5 DO

SET str = CONCAT(str,x,',')

SET x = x + 1

END WHILE

SELECT str

END //

delimiter

后来发现有些图片没有抓过来,而产品已经上线,重新抓取数据已是不现实的事情了。于是和同事协商后干脆把图片所在块一起去掉。攻略文章不再展示“卡牌数值”的图片表格。实现方法是采用MySQL的一些不太常用的函数。

[sql] view plain copy

SELECT replace(content,SUBSTRING(content FROM POSITION("卡牌数值" IN content) FOR POSITION("-->" IN content)),"</span></h3></div>")

as x from CONTENT_TABLE c

where c.news_id in (select news_id from NEWS_TABLE where col_id = 66)

update CONTENT_TABLE c

set c.content = replace(c.content,SUBSTRING(c.content FROM POSITION("卡牌数值" IN c.content) FOR POSITION("-->" IN c.content)),"</span></h3></div>")

where c.news_id in (select news_id from NEWS_TABLE where col_id = 66)

鉴于抓来的html结构比较乱比较复杂,也只能这样了。尽管效率一般,不过相关的文章不过几百篇,还可以接受的解决方法。关于其中涉及的SQL函数这里再重温学习一下:

一、MySQL中LOCATE和别名函数POSITION等

函数LOCATE(substr,str) 作用同POSITION(substr IN str)和INSTR(str,substr)

作用:返回子串 substr 在字符串 str 中第一次出现的位置。如果子串 substr 在 str 中不存在,返回值为 0;LOCATE还有一种形式,包含三个参数:LOCATE(substr,str,pos) ,其返回子串 substr 在字符串 str 中的第 pos 位置后第一次出现的位置。INSTR(str,substr)和LOCATE()的双参数形式相同,只是参数顺序不一样而已。

mysql>SELECT LOCATE('bar', 'foobarbar')

->4

mysql>SELECT INSTR('foobarbar', 'bar')

->4

mysql>SELECT LOCATE('xbar', 'foobar')

->0

mysql>SELECT INSTR('xbar', 'foobar')

->0

mysql>SELECT LOCATE('bar', 'foobarbar', 7)

->7

这个函数是多字节安全的。在 MySQL 3.23 中,这个函数是字母大小写敏感的,当在 MySQL 4.0 中时,如有任一参数是一个二进制字符串,它才是字母大小写敏感的。

以下语句可以实现同样的查询功能:

SELECT `column` FROM `table` where `condition` like `%keyword%’

SELECT `column` from `table` where locate(‘keyword’, `condition`)>0

SELECT `column` from `table` where position(‘keyword’ IN `condition`)

SELECT `column` from `table` where instr(`condition`, ‘keyword’ )>0

速度上后三个比使用 like 稍快了一点点。

二、MySQL的REPLACE用法

用法一:函数REPLACE(str,from_str,to_str)

在字符串 str 中所有出现的字符串 from_str 均被 to_str替换,然后返回这个字符串:

mysql>select REPLACE('www.8783.com/a/detail_list/', 'a', 'list')

->www.8783.com/list/detlistil_list/

例:把表table中的name字段中的 '斗三国'替换为“全民斗三国”

mysql>update table set name=replace(name,'斗三国','全民斗三国')

这个函数也是多字节安全的。

用法二:REPLACE INTO

在向表中插入数据的时候,经常遇到这样的情况:1. 首先判断数据是否存在; 2. 如果不存在,则插入;3.如果存在,则更新。包括我在内的程序猿们常见的做法有三种:

第一种:MySQL很常见的一种做法,许多新手、甚至许多资深的高级coder也有这么写的,会在代码中封装三个函数,一个函数查询记录是否存在,一个函数实现直接插入,另一个函数对已有记录进行更新。在不同的情况进行调用。这种方法多次excute执行数据 *** 作,势必造成比较大的开销。

第二种:用一条SQL代替三种情况的封装,来实现按需 *** 作,或插入新记录,或更新旧数据。SQL Server中的语句如下:

IF NOT EXISTS(select 1 from NEWS_bak where news_id = 1008)

insert into NEWS_bak(title, keyword, description) values('孙权', '三国','孙权-吴国老大')

else

update NEWS_bak set title = '孙权'and keyword='三国' and description='孙权-吴国老大' where news_id = 1008

说明:对于IF NOT EXISTS的相同表达,MySQL一般用作条件WHERE NOT EXISTS()由于exists(SELECT NULL )也会返回true,故select exists(SELECT NULL )的结果为1。

但是在MySQL 中如何实现此逻辑呢?方法有,且语法更简洁——replace into 。

MySQL replace into 有三种形式:

1. replace into tbl_name(col_name, ...) values(...)

2. replace into tbl_name(col_name, ...) select ...

3. replace into tbl_name set col_name=value, ...

前两种形式使用频度比较高。其中 “into” 关键字可以省略,不过最好加上 “into”,这样意思更加直观。所有列的值均取自在REPLACE语句中被指定的值。所有缺失的列被设置为各自的默认值,这和INSERT一样。您不能从当前行中引用值,也不能在新行中使用值。如果您使用一个例如“SET col_name = col_name + 1”的赋值,则对位于右侧的列名称的引用会被作为DEFAULT(col_name)处理。因此,该赋值相当于SET col_name = DEFAULT(col_name) + 1。

举例:

replace into tableName (id,index) values('1','index-A'),('2','index-B')

此语句用于向表tableName中插入两条记录。 replace into 跟 insert 功能类似,不同点在于:replace into 首先尝试插入数据到表中,如果发现表中已经有此行数据(根据主键或者唯一索引判断)则先删除此行数据,然后插入新的数据否则,直接插入新的数据。

为了能够使用REPLACE,您必须同时拥有表的INSERT和DELETE权限。

REPLACE语句会返回一个数,来指示受影响的行的数目。该数是被删除和被插入的行数的和。如果对于一个单行REPLACE该数为1,则一行被插入,同时没有行被删除。如果该数大于1,则在新行被插入前,有一个或多个旧行被删除。如果表包含多个唯一索引,并且新行复制了在不同的唯一索引中的不同旧行的值,则有可能是一个单一行替换了多个旧行。

PHP可以使用mysql_affected_rows()函数获得受影响的行数。受影响的行数可以容易地确定是否REPLACE只添加了一行,或者是否REPLACE也替换了其它行:只需检查该数是否为1(添加)或更大(替换)。

必须注意:插入数据的表必须有主键PRIMARY KEY或者是唯一索引UNIQUE!否则,使用一个REPLACE语句没有意义。该语句会与INSERT相同,因为没有索引被用于确定是否新行复制了其它的行。这时,replace into 会直接插入数据,这将导致表中出现重复的数据。

三、MySQL SUBSTRING 函数的使用

SUBSTRING ( expression , start , length )

参数:

expression 是字符串、二进制字符串、text、image、列或包含列的表达式。不要使用包含聚合函数的表达式。

start是一个整数,指定子串的开始位置。若为负数,则从字符串末尾倒数。

length是一个整数,可选,指定子串的长度(要返回的字符数或字节数)。

函数共有4种格式:

SUBSTRING(str,pos) ,

SUBSTRING(str FROM pos) ,

SUBSTRING(str,pos,len) ,

SUBSTRING(str FROM pos FOR len)

不带有len 参数的格式从字符串str返回一个子字符串,起始于位置 pos。带有len参数的格式从字符串str返回一个长度同len字符相同的子字符串,起始于位置 pos。 使用 FROM的格式为标准 SQL 语法。也可能对pos使用一个负值。假若这样,则子字符串的位置起始于字符串结尾的pos 字符,而不是字符串的开头位置。在以下格式的函数中可以对pos 使用一个负值。

说明

由于在 text 数据上使用 SUBSTRING 时 start 和 length 指定字节数,因此 DBCS 数据(如日本汉字)可能导致在结果的开始或结束位置拆分字符。此行为与 READTEXT 处理 DBCS 的方式一致。然而,由于偶而会出现奇怪的结果,建议对 DBCS 字符使用 ntext 而非 text 。

返回类型

如果 expression 是支持的字符数据类型,则返回字符数据。如果expression 是支持的 binary 数据类型,则返回二进制数据。一般实际使用中text 数据多以 varchar 的形式返回,image 数据则以 varbinary 的形式返回。

返回字符串的类型与给定表达式的类型相同(表中显示的除外)。

Innodb的四个特性

在介绍Innodb预读特性之前,笔者有必要介绍一下 *** 作系统的局部性原理,这样方便于读者理解Innodb的一个强大特性-----预读。

局部性原理

一个优秀额程序通常会有良好的局部性,所谓局部性指的是一个应用程序通常会重复使用某块内存区域中的数据,或者使用该区域邻近内存区域的数据。默认情况下当 *** 作系统监测到某块内存区的数据将要被重复使用或者邻近的数据将要被使用时, *** 作系统会一次性将相邻的若干个数据块同时加载到内存缓冲区中。局部性原理分为以下两种:

有了以上局部性原理的知识基础之后,我们再来理解预读的原理就相对简单多了。可以简单的理解为:当Innodb监测到某一块磁盘空间的数据将要被读取时邻近的数据很快将要被使用,Innodb会一次性仅通过一次IO *** 作将数据读取到内存缓冲池中。Innodb中预读包含两种模式:

何时触发Innodb预读功能可以通过如下配置来控制

双写缓冲区:双写缓冲是一种特殊的文件刷新技术,它涉及到一种称为双写缓冲区的数据结构。在默认情况下Innodb默认开启该功能(dubblewrite_buffer=ON),他增加意外退出和断电后的数据恢复的安全性,并减少文件同步(fsync()) *** 作来提高数据库的性能。

在将页面写入数据文件之前, InnoDB 首先将它们写入称为双写缓冲区的连续表空间区域。只有在对双写缓冲区的写入和刷新完成后,才会 InnoDB 将页面写入数据文件中的适当位置。如果在页面写入过程中存在 *** 作系统、存储子系统或意外 的 mysqld 进程退出(导致 页面撕裂 的 情况), InnoDB 则可以稍后在恢复期间从双写缓冲区中找到该页面的良好副本。

双写缓冲的实现过程 : 对缓冲池的脏页进行刷新时,不是直接写磁盘,而是会通过memcpy()函数将脏页先复制到内存中的doublewrite buffer,之后通过doublewrite 再分两次,每次1M顺序地写入共享表空间的物理磁盘上,在这个过程中,因为doublewrite页是连续的,因此这个过程是顺序写的,开销并不是很大。在完成doublewrite页的写入后,再将doublewrite buffer 中的页写入各个 表空间文件中,此时的写入则是离散的。如果 *** 作系统在将页写入磁盘的过程中发生了崩溃,在恢复过程中,innodb可以从共享表空间中的doublewrite中找到该页的一个副本,将其复制到表空间文件,再应用重做日志。

注意:将数据页写如文件的时候,Innodb会将数据写入redo log日志文件中,当完全写入redo log文件之后会设置一个prepare状态,然后再将数据写入dubbo write buffer中,当意外突出或者断电,数据库恢复数据时会先检查redo log日志文件中是否有prepare状态,如果有直接使用dubble write buffer恢复数据,如果dubble write buffer不可用则使用redo log文件恢复数据,这种方式称为二阶段提交方式。

数据写顺序:redo log --->dubble write buffer - 通用表空间---->指定表空间

innodb使用insert buffer"欺骗"数据库:对于为非唯一索引,辅助索引的修改 *** 作并非实时更新索引的叶子页,而是把若干对同一页面的更新缓存起来做合并为一次性更新 *** 作,转化随机IO 为顺序IO,这样可以避免随机IO带来性能损耗,提高数据库的写性能。

插入缓冲的配置

当缓冲池中的某个数据(17次)或者某个页(100次)经常被访问,达到一定频率的时候,Innodb会根据缓冲池中的数据自动构建一个hash索引,提高数据的访问速度,该索引称为自适应哈希索引。

Innodb存储引擎会监控对表上二级索引的查找,如果发现某二级索引被频繁访问,二级索引成为热数据,建立哈希索引可以带来速度的提升

经常访问的二级索引数据会自动被生成到hash索引里面去(最近连续被访问三次的数据),自适应哈希索引通过缓冲池的B+树构造而来,因此建立的速度很快。

哈希(hash)是一种非常快的等值查找方法 ,在一般情况下这种查找的时间复杂度为O(1),即一般仅需要一次查找就能定位数据。而B+树的查找次数,取决于B+树的高度,在生产环境中,B+树的高度一般3-4层,故需要3-4次的查询

篇尾寄语:

技术赋能于业务,希望本篇文章让每一位读者有所收益...................................................

如有不当的地方请多多计较,共同学习,共同进步,fighting............................................

祝所有编程爱好者,求职,加薪,迎娶白富美,走向人生巅峰........................................

据统计,我国电子商务企业已达到1000多万家,其中大中型企业就有10万多家,初步估计,未来我国对电子商务人才的需求每年约80万人,而我国目前包括高校和各类培训机构每年输出的人才数量不到10万人。人才缺口巨大已成为制约我国电商行业发展的一大瓶颈。

选择江西新华电脑学院云电商工程师专业,你将学习:

电子商务概论与政策法规、Photoshop图像处理、电子商务物流管理、HTML5+CSS3、WEB和移动界面商业案例、Windows Server2003服务器 *** 作系统、动态网页设计PHPMYSQL、网络数据库基础(SQLServer)、JavaScript、电子商务安全与网上支付、百度SEM、SEO优化与推广、网络营销及综合实践等。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/7356964.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-04
下一篇2023-04-04

发表评论

登录后才能评论

评论列表(0条)

    保存