1. 主页 > 热点营销资讯

js中怎么使用正则表达式语法,js正则表达式格式使用教程

高价值的内容是做好企业营销推广的前提,如果你对企业内容营销感兴趣的话,不妨看看MarketUP近期整理的《2023内容营销获客实战白皮书》,希望能给大家有一些实质性的帮助,预计发布400份!送完下架,赶快领取!感兴趣的朋友可以点击链接即可下载阅读:《2023内容营销获客实战白皮书》

js中怎么使用正则表达式语法,js正则表达式格式使用教程(图1)

是什么

正则表达式是一种用来匹配字符串的强有力的武器

它的设计思想是用一种描述性的语言定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的

根据正则表达式语法规则,大部分字符仅能够描述自身,这些字符被称为普通字符,如所有的字母、数字等。元字符就是拥有特动功能的特殊字符,大部分需要加反斜杠进行标识,以便于普通字符进行区别,而少数元字符,需要加反斜杠,以便转译为普通字符使用。JavaScript 正则表达式支持的元字符如表所示。

在 JavaScript中,正则表达式也是对象,构建正则表达式有两种方式:

  1. 字面量创建,其由包含在斜杠之间的模式组成

constre = /\d+/g;

  1. 调用RegExp对象的构造函数

constre = newRegExp(“\\d+”,”g”); construl = “\\d+”constre1 = newRegExp(rul,”g”);

使用构建函数创建,第一个参数可以是一个变量,遇到特殊字符\需要使用\\进行转义

表示字符的方法有多种,除了可以直接使用字符本身外,还可以使用 ASCII 编码或者 Unicode 编码来表示。

示例1

下面使用 ASCII 编码定义正则表达式直接量。

varr = /\x61/;vars = “JavaScript”;vara = s.match(s);

由于字母 a 的 ASCII 编码为 97,被转换为十六进制数值后为 61,因此如果要匹配字符 a,就应该在前面添加“\x”前缀,以提示它为 ASCII 编码。

示例2

除了十六进制外,还可以直接使用八进制数值表示字符。

varr = /\141/;vars = “JavaScript”;vara = s.match(r);

使用十六进制需要添加“\x”前缀,主要是为了避免语义混淆,而八进制则不需要添加前缀。

示例3

ASCII 编码只能够匹配有限的单字节字符,使用 Unicode 编码可以表示双字节字符。Unicode 编码方式:“\u”前缀加上 4 位十六进制值。

varr = “/\u0061/”;vars = “JavaScript”;vara = s.match(s);

在 RegExp() 构造函数中使用元字符时,应使用双斜杠。

varr = newRegExp(“\\u0061”);

RegExp() 构造函数的参数只接受字符串,而不是字符模式。在字符串中,任何字符加反斜杠还表示字符本身,如字符串“\u”就被解释为 u 本身,所以对于“\u0061”字符串来说,在转换为字符模式时,就被解释为“u0061”,而不是“\u0061”,此时反斜杠就失去转义功能。解决方法:在字符 u 前面加双反斜杠。

匹配规则

常见的校验规则如下:

规则

描述

\

转义

^

匹配输入的开始

$

匹配输入的结束

*

匹配前一个表达式 0 次或多次

+

匹配前面一个表达式 1 次或者多次。等价于 {1,}

?

匹配前面一个表达式 0 次或者 1 次。等价于{0,1}

.

默认匹配除换行符之外的任何单个字符

x(?=y)

匹配’x’仅仅当’x’后面跟着’y’。这种叫做先行断言

(?<=y)x

匹配’x’仅当’x’前面是’y’.这种叫做后行断言

x(?!y)

仅仅当’x’后面不跟着’y’时匹配’x’,这被称为正向否定查找

(?<!y)x

仅仅当’x’前面不是’y’时匹配’x’,这被称为反向否定查找

x|y

匹配‘x’或者‘y’

{n}

n 是一个正整数,匹配了前面一个字符刚好出现了 n 次

{n,}

n是一个正整数,匹配前一个字符至少出现了n次

{n,m}

n 和 m 都是整数。匹配前面的字符至少n次,最多m次

[xyz]

一个字符集合。匹配方括号中的任意字符

[^xyz]

匹配任何没有包含在方括号中的字符

\b

匹配一个词的边界,例如在字母和空格之间

\B

匹配一个非单词边界

\d

匹配一个数字

\D

匹配一个非数字字符

\f

匹配一个换页符

\n

匹配一个换行符

\r

匹配一个回车符

\s

匹配一个空白字符,包括空格、制表符、换页符和换行符

\S

匹配一个非空白字符

\w

匹配一个单字字符(字母、数字或者下划线)

\W

匹配一个非单字字符

正则表达式标记

标志

描述

g

全局搜索。

i

不区分大小写搜索。

m

多行搜索。

s

允许 .匹配换行符。

u

使用unicode码的模式进行匹配。

y

执行“粘性(sticky)”搜索,匹配从目标字符串的当前位置开始。

使用方法如下:

varre = /pattern/flags; varre = newRegExp(“pattern”, “flags”);

在了解下正则表达式基本的之外,还可以掌握几个正则表达式的特性:

贪婪模式

在了解贪婪模式前,首先举个例子:

constreg = /ab{1,3}c/

在匹配过程中,尝试可能的顺序是从多往少的方向去尝试。首先会尝试bbb,然后再看整个正则是否能匹配。不能匹配时,吐出一个b,即在bb的基础上,再继续尝试,以此重复

如果多个贪婪量词挨着,则深度优先搜索

const string= “12345”; const regx = /(\d{1,3})(\d{1,3})/; console.log( string.match(reg) ); // => [“12345”, “123”, “45”, index: 0, input: “12345”]

其中,前面的\d{1,3}匹配的是”123″,后面的\d{1,3}匹配的是”45″

懒惰模式

惰性量词就是在贪婪量词后面加个问号。表示尽可能少的匹配

var string= “12345”; var regex = /(\d{1,3}?)(\d{1,3})/; console.log( string.match(regex) ); // => [“1234”, “1”, “234”, index: 0, input: “12345”]

其中\d{1,3}?只匹配到一个字符”1″,而后面的\d{1,3}匹配了”234″

分组

分组主要是用过()进行实现,比如beyond{3},是匹配d字母3次。而(beyond){3}是匹配beyond三次

在()内使用|达到或的效果,如(abc | xxx)可以匹配abc或者xxx

反向引用,巧用$分组捕获

letstr = “John Smith”; // 交换名字和姓氏console.log(str.replace(/(john) (smith)/i, ‘$2, $1’)) // Smith, John

匹配方法

正则表达式常被用于某些方法,我们可以分成两类:

  • 字符串(str)方法:match、matchAll、search、replace、split
  • 正则对象下(regexp)的方法:test、exec
  • 方法

    描述

    exec

    一个在字符串中执行查找匹配的RegExp方法,它返回一个数组(未匹配到则返回 null)。

    test

    一个在字符串中测试是否匹配的RegExp方法,它返回 true 或 false。

    match

    一个在字符串中执行查找匹配的String方法,它返回一个数组,在未匹配到时会返回 null。

    matchAll

    一个在字符串中执行查找所有匹配的String方法,它返回一个迭代器(iterator)。

    search

    一个在字符串中测试匹配的String方法,它返回匹配到的位置索引,或者在失败时返回-1。

    replace

    一个在字符串中执行查找匹配的String方法,并且使用替换字符串替换掉匹配到的子字符串。

    split

    一个使用正则表达式或者一个固定字符串分隔一个字符串,并将分隔后的子字符串存储到数组中的 String方法。

    str.match(regexp)

    str.match(regexp)方法在字符串 str中找到匹配 regexp的字符

    如果 regexp不带有 g标记,则它以数组的形式返回第一个匹配项,其中包含分组和属性 index(匹配项的位置)、input(输入字符串,等于 str)

    letstr = “I love JavaScript”; letresult = str.match(/Java(Script)/); console.log( result[0] ); // JavaScript(完全匹配)console.log( result[1] ); // Script(第一个分组)console.log( result.length ); // 2// 其他信息:console.log( result.index ); // 7(匹配位置)console.log( result.input ); // I love JavaScript(源字符串)

    如果 regexp带有 g标记,则它将所有匹配项的数组作为字符串返回,而不包含分组和其他详细信息

    letstr = “I love JavaScript”; letresult = str.match(/Java(Script)/g); console.log( result[0] ); // JavaScriptconsole.log( result.length ); // 1

    如果没有匹配项,则无论是否带有标记 g,都将返回 null

    letstr= “I love JavaScript”; letresult = str.match(/HTML/); console.log(result); // null

    str.matchAll(regexp)

    返回一个包含所有匹配正则表达式的结果及分组捕获组的迭代器

    const regexp = /t(e)(st(\d?))/g; const str = ‘test1test2’; const array = […str.matchAll(regexp)]; console.log(array[0]); // expected output: Array [“test1”, “e”, “st1”, “1”] console.log(array[1]); // expected output: Array [“test2”, “e”, “st2”, “2”]

    str.search(regexp)

    返回第一个匹配项的位置,如果未找到,则返回 -1

    letstr = “A drop of ink may make a million think”; console.log( str.search( /ink/i) ); // 10(第一个匹配位置)

    这里需要注意的是,search仅查找第一个匹配项

    str.replace(regexp)

    替换与正则表达式匹配的子串,并返回替换后的字符串。在不设置全局匹配g的时候,只替换第一个匹配成功的字符串片段

    constreg1=/javascript/i; constreg2=/javascript/ig; console.log(‘hello Javascript Javascript Javascript’.replace(reg1,’js’)); //hello js Javascript Javascriptconsole.log(‘hello Javascript Javascript Javascript’.replace(reg2,’js’)); //hello js js js

    str.split(regexp)

    使用正则表达式(或子字符串)作为分隔符来分割字符串

    console.log(’12, 34, 56′.split(/,\s*/)) //数组 [’12’, ’34’, ’56’]

    #regexp.exec(str)

    regexp.exec(str)方法返回字符串 str中的 regexp匹配项,与以前的方法不同,它是在正则表达式而不是字符串上调用的

    根据正则表达式是否带有标志 g,它的行为有所不同

    如果没有 g,那么 regexp.exec(str)返回的第一个匹配与 str.match(regexp)完全相同

    如果有标记 g,调用 regexp.exec(str)会返回第一个匹配项,并将紧随其后的位置保存在属性regexp.lastIndex中。 下一次同样的调用会从位置 regexp.lastIndex开始搜索,返回下一个匹配项,并将其后的位置保存在 regexp.lastIndex中

    letstr = ‘More about JavaScript at https://javascript.info’; letregexp = /javascript/ig; letresult; while(result = regexp.exec(str)) { console.log( `Found ${result[0]}at position ${result.index}`); // Found JavaScript at position 11// Found javascript at position 33}

    regexp.test(str)

    查找匹配项,然后返回 true/false表示是否存在

    letstr = “I love JavaScript”; // 这两个测试相同console.log( /love/i.test(str) ); // true

    应用场景

    通过上面的学习,我们对正则表达式有了一定的了解

    下面再来看看正则表达式一些案例场景:

    验证QQ合法性(5~15位、全是数字、不以0开头):

    const reg = /^[1-9][0-9]{4,14}$/ const isvalid = patrn.exec(s)

    校验用户账号合法性(只能输入5-20个以字母开头、可带数字、“_”、“.”的字串):

    varpatrn=/^[a-zA-Z]{1}([a-zA-Z0-9]|[._]){4,19}$/; constisvalid = patrn.exec(s)

    将url参数解析为对象

    constprotocol = ‘(?<protocol>https?:)’; consthost = ‘(?<host>(?<hostname>[^/#?:]+)(?::(?<port>\\d+))?)’; constpath = ‘(?<pathname>(?:\\/[^/#?]+)*\\/?)’; constsearch = ‘(?<search>(?:\\?[^#]*)?)’; consthash = ‘(?<hash>(?:#.*)?)’; constreg = newRegExp(`^${protocol}\/\/${host}${path}${search}${hash}$`); functionexecURL(url){ constresult = reg.exec(url); if(result){ result.groups.port = result.groups.port || ”; returnresult.groups; } return{ protocol:”,host:”,hostname:”,port:”, pathname:”,search:”,hash:”, }; } console.log(execURL(‘https://localhost:8080/?a=b#xxxx’)); protocol: “https:”host: “localhost:8080″hostname: “localhost”port: “8080”pathname: “/”search: “?a=b”hash: “#xxxx”

    再将上面的search和hash进行解析

    functionexecUrlParams(str){ str = str.replace(/^[#?&]/,”); constresult = {}; if(!str){ //如果正则可能配到空字符串,极有可能造成死循环,判断很重要returnresult; } constreg = /(?:^|&)([^&=]*)=?([^&]*?)(?=&|$)/yletexec = reg.exec(str); while(exec){ result[exec[1]] = exec[2]; exec = reg.exec(str); } returnresult; } console.log(execUrlParams(‘#’));// {}console.log(execUrlParams(‘##’));//{‘#’:”}console.log(execUrlParams(‘?q=3606&src=srp’)); //{q: “3606”, src: “srp”}console.log(execUrlParams(‘test=a=b=c&&==&a=’));//{test: “a=b=c”, “”: “=”, a: “”}

    ECMAScript正则表达式6个最新特性

    1. dotAll模式(s选项)

    这个特性已经在ECMAScript 2018正式发布了。

    默认情况下,.可以匹配任意字符,除了换行符:

    /foo.bar/u.test(‘foo\nbar’); //false

    另外,.不能匹配Unicode字符,需要使用u选项启用Unicode模式才行。

    ES2018引入了dotAll模式,通过s选项可以启用,这样,.就可以匹配换行符了。

    /foo.bar/su.test(‘foo\nbar’); //true

    2. Lookbehind断言

    这个特性已经在ECMAScript 2018正式发布了。

    ECMAScript目前仅支持lookahead断言。

    下面示例是Positive lookahead,匹配字符串“42 dollars”中紧跟着是”dollars”的数字:

    constpattern = /\d+(?= dollars)/u; constresult = pattern.exec(’42 dollars’); console.log(result[0]); // 打印42

    下面示例是Negative lookahead,匹配字符串“42 pesos”中紧跟着的不是”dollars”的数字:

    constpattern = /\d+(?! dollars)/u; constresult = pattern.exec(’42 pesos’); console.log(result[0]); // 打印42

    ES2018添加了lookbehind断言。

    下面示例是Positive lookbehind,匹配字符串“$42”中前面是”\$”的数字:

    constpattern = /(?<=\$)\d+/u; constresult = pattern.exec(‘$42’); console.log(result[0]); // 打印42

    下面示例是Negative lookbehind,匹配字符串“$42”中前面不是是”\$”的数字:

    constpattern = /(?<!\$)\d+/u; constresult = pattern.exec(‘€42’); console.log(result[0]); // 打印42

    Fundebug专注于网页、微信小程序、微信小游戏,支付宝小程序,React Native,Node.js和Java线上BUG实时监控,欢迎免费试用

    3. Named capture groups

    这个特性已经在ECMAScript 2018正式发布了。

    目前,正则表达式中小括号匹配的分组是通过数字编号的:

    constpattern = /(\d{4})-(\d{2})-(\d{2})/u; constresult = pattern.exec(‘2017-01-25’); console.log(result[0]); // 打印”2017-01-25″console.log(result[1]); // 打印”2017″console.log(result[2]); // 打印”01″console.log(result[3]); // 打印”25″

    这样很方便,但是可读性很差,且不易维护。一旦正则表达式中小括号的顺序有变化时,我们就需要更新对应的数字编号。

    ES2018添加named capture groups, 可以指定小括号中匹配内容的名称,这样可以提高代码的可读性,也便于维护。

    constpattern = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u; constresult = pattern.exec(‘2017-01-25’); console.log(result.groups.year); // 打印”2017″console.log(result.groups.month); // 打印”01″console.log(result.groups.day); // 打印”25″

    4. Unicode property escapes

    这个特性已经在ECMAScript 2018正式发布了。

    Unicode标准为每一个字符分配了多个属性。比如,当你要匹配希腊语字符时,则可以搜索Script_Extensions属性为Greek的字符。

    Unicode property escapes使得我们可以使用ECMAScript正则表达式直接匹配Unicode字符的属性:

    constregexGreekSymbol = /\p{Script_Extensions=Greek}/u; console.log(regexGreekSymbol.test(‘π’)); // 打印true

    5. String.prototype.matchAll

    这个特性还处在Stage 3 Draft

    g和y选项通常用于匹配一个字符串,然后遍历所有匹配的子串,包括小括号匹配的分组。String.prototype.matchAll让这个操作变得更加简单了。

    conststring= ‘Magic hex numbers: DEADBEEF CAFE 8BADF00D’; constregex = /\b[0-9a-fA-F]+\b/g; for(constmatch of string.matchAll(regex)) { console.log(match); }

    每一个迭代所返回的match对象与regex.exec(string)所返回的结果相同:

    // Iteration 1:[ ‘DEADBEEF’, index: 19, input: ‘Magic hex numbers: DEADBEEF CAFE 8BADF00D’ ] // Iteration 2:[ ‘CAFE’, index: 28, input: ‘Magic hex numbers: DEADBEEF CAFE 8BADF00D’ ] // Iteration 3:[ ‘8BADF00D’, index: 33, input: ‘Magic hex numbers: DEADBEEF CAFE 8BADF00D’ ]

    注意,这个特性还处在Stage 3 Draft,因此还存在变化的可能性,示例代码是根据最新的提案写的。另外,浏览器也还没有支持这个特性。String.prototype.matchAll最快可以被加入到ECMAScript 2019中。

    6. 规范RegExp遗留特性

    这个提案还处在Stage 3 Draft

    这个提案规范了RegExp的遗留特性,比如RegExp.prototype.compile方法以及它的静态属性从RegExp.$1到RegExp.$9。虽然这些特性已经弃用(deprecated)了,但是为了兼容性我们不能将他们去。因此,规范这些RegExp遗留特性是最好的方法。因此,这个提案有助于保证兼容性。

    常用验证

    /** * @param {string} path * @returns {Boolean} */ export function isExternal(path) { return /^(https?:|mailto:|tel:)/.test(path) } /** * @param {string} str * @returns {Boolean} */ export function validUsername(str) { const valid_map = [‘admin’, ‘editor’] return valid_map.indexOf(str.trim()) >= 0 } /** * @param {string} url * @returns {Boolean} */ export function validURL(url) { const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?’\\+&%$#=~_-]+))*$/ return reg.test(url) } /** * @param {string} str * @returns {Boolean} */ export function validLowerCase(str) { const reg = /^[a-z]+$/ return reg.test(str) } /** * @param {string} str * @returns {Boolean} */ export function validUpperCase(str) { const reg = /^[A-Z]+$/ return reg.test(str) } /** * @param {string} str * @returns {Boolean} */ export function validAlphabets(str) { const reg = /^[A-Za-z]+$/ return reg.test(str) } /** * @param {string} email * @returns {Boolean} */ export function validEmail(email) { const reg = /^(([^<>()\[\]\\.,;:\s@”]+(\.[^<>()\[\]\\.,;:\s@”]+)*)|(“.+”))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ return reg.test(email) } /** * @param {string} str * @returns {Boolean} */ export function isString(str) { if (typeof str === ‘string’ || str instanceof String) { return true} return false } /** * @param {Array} arg * @returns {Boolean} */ export function isArray(arg) { if (typeof Array.isArray === ‘undefined’) { return Object.prototype.toString.call(arg) === ‘[object Array]’} return Array.isArray(arg) }

    TS版

    /** * @param {string}path* @returns {Boolean}*/exportfunctionisExternal(path) { return/^(https?:|mailto:|tel:)/.test(path); } /** * @param {string}str* @returns {Boolean}*/exportfunctionvalidUsername(str) { constvalid_map = [‘admin’, ‘editor’]; returnvalid_map.indexOf(str.trim()) >= 0; } /** * @param {string}url* @returns {Boolean}*/exportfunctionvalidURL(url) { constreg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?’\\+&%$#=~_-]+))*$/; returnreg.test(url); } /** * @param {string}str* @returns {Boolean}*/exportfunctionvalidLowerCase(str) { constreg = /^[a-z]+$/; returnreg.test(str); } /** * @param {string}str* @returns {Boolean}*/exportfunctionvalidUpperCase(str) { constreg = /^[A-Z]+$/; returnreg.test(str); } /** * @param {string}str* @returns {Boolean}*/exportfunctionvalidAlphabets(str) { constreg = /^[A-Za-z]+$/; returnreg.test(str); } /** * @param {string}email* @returns {Boolean}*/exportfunctionvalidEmail(email) { constreg = /^(([^<>()\[\]\\.,;:\s@”]+(\.[^<>()\[\]\\.,;:\s@”]+)*)|(“.+”))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; returnreg.test(email); } /** * @param {string}phone* @returns {Boolean}*/exportfunctionvalidPhone(phone) { constreg = /^1[3-9][0-9]{9}$/; returnreg.test(phone); } /** * @param {string}str* @returns {Boolean}*/exportfunctionisString(str) { if(typeofstr === ‘string’|| str instanceofString) { returntrue; } returnfalse; } /** * @param {Array}arg* @returns {Boolean}*/exportfunctionisArray(arg) { if(typeofArray.isArray === ‘undefined’) { returnObject.prototype.toString.call(arg) === ‘[object Array]’; } returnArray.isArray(arg); } // [修改]-新增-开始/** * 英文验证 * @param min* @param max* @param value*/exportfunctionenglish(value: string, min = 6, max = 12): boolean{ returnnewRegExp(‘^[a-z|A-Z]{‘+ min + ‘,’+ max + ‘}$’).test(value); } /** * 中文验证 * @param min* @param max* @param value*/exportfunctionchinese(value: string, min = 2, max = 12): boolean{ returnnewRegExp(‘^[\u4e00-\u9fa5]{‘+ min + ‘,’+ max + ‘}$’).test(value); } /** * 非中文 * @param value 内容 * @returns boolean*/exportfunctionnotChinese(value: string): boolean{ return!/[\u4e00-\u9fa5]/.test(value); } /** * 必需数字 * @param min* @param max* @param value*/exportfunctionnumber(value: string, min = 1, max = 20): boolean{ returnnewRegExp(‘^d{‘+ min + ‘,’+ max + ‘}$’).test(value); } /** * 必需小数点最大值 * @param min* @param max* @param value*/exportfunctionprecision(value: string, max = 8, precision = 8): boolean{ returnnewRegExp( ‘(^[0-9]{1,’+ max + ‘}$)|(^[0-9]{1,’+ max + ‘}[.]{1}[0-9]{1,’+ precision + ‘}$)’, ).test(value); } /** * 复杂密码验证 * @param value*/exportfunctionpwd(value: string): boolean{ if(value && value.length > 15) { consten = /[a-z]/.test(value); constnum = /[0-9]/.test(value); constdaxie = /[A-Z]/.test(value); constteshu = /[~!@#$%^&*()_+=-\[\]\\,.\/;’:{}]/.test(value); returnen && num && daxie && teshu; } returnfalse; } // [修改]-新增-结束

    以上就是今天分享的全部内容,希望能够对广大企业营销人员有一些营销方面的启发。作为国内知名的营销自动化平台,MarketUP通过完善的企业营销自动化系统,帮助企业实现有效和有意义的企业营销工作,更好地满足您每个目标受众端到端的需求,为您的渠道带来更多理想的潜在客户并留存孵化。如果您对我们的营销自动化产品或功能感兴趣,欢迎点击【这里】进行演示申请,我们将有专业的团队为您提供服务。

    本文由MarketUP营销自动化博客发布,不代表MarketUP立场,转载联系作者并注明出处:https://www.marketup.cn/marketupblog/yxzx/14464.html

    联系我们

    手机号:19951984030

    微信号:marketup01

    工作日:8:30-18:00,节假日休息