자바스크립트에서 긴 정규식을 여러 줄로 분할하는 방법은 무엇입니까?
저는 매우 긴 정규 표현식을 가지고 있는데, JSLint 규칙에 따라 각 줄의 길이를 80자로 유지하기 위해 자바스크립트 코드에서 여러 줄로 나누고 싶습니다.그냥 읽기에 더 좋은 것 같아요.다음은 패턴 샘플입니다.
var pattern = /^(([^<>()[\]\\.,;:\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,}))$/;
@KuiInc 응답을 확장하면 모든 특수 문자를 수동으로 이스케이프하는 것을 피할 수 있습니다.source
의 RegExp
물건.
예:
var urlRegex = new RegExp(
/(?:(?:(https?|ftp):)?\/\/)/.source // protocol
+ /(?:([^:\n\r]+):([^@\n\r]+)@)?/.source // user:pass
+ /(?:(?:www.)?([^/\n\r]+))/.source // domain
+ /(\/[^?\n\r]+)?/.source // request
+ /(\?[^#\n\r]*)?/.source // query
+ /(#?[^\n\r]*)?/.source // anchor
);
또는 반복하지 않으려면.source
은 성을사수수있습다니행할을 하여 할 수 .Array.map()
함수:
var urlRegex = new RegExp([
/(?:(?:(https?|ftp):)?\/\/)/, // protocol
/(?:([^:\n\r]+):([^@\n\r]+)@)?/, // user:pass
/(?:(?:www.)?([^/\n\r]+))/, // domain
/(\/[^?\n\r]+)?/, // request
/(\?[^#\n\r]*)?/, // query
/(#?[^\n\r]*)?/, // anchor
].map(function (r) { return r.source; }).join(''));
다음과 같이 수 ..map(r => r.source)
.
[편집 2022/08] 작은 github 저장소를 생성하여 공간, 주석 및 템플릿으로 정규 표현을 생성하였습니다.
문자열로 변환하고 다음을 호출하여 식을 만들 수 있습니다.new RegExp()
:
var myRE = new RegExp (['^(([^<>()[\]\\.,;:\\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,}))$'].join(''));
주의:
표현식 리터럴을 문자열로 변환할 때 문자열 리터럴을 평가할 때 백슬래시가 사용되므로 모든 백슬래시를 피해야 합니다.(자세한 내용은 카요의 코멘트를 참조하십시오.
RegExp
를 두 변수로 할 수 있습니다./regex/g
=>new RegExp('regex', 'g')
[추가 ES20xx(태그 부착 템플릿)]
ES20xx에서는 태그가 지정된 템플릿을 사용할 수 있습니다.스니펫을 참조하십시오.
참고:
- 여기서 단점은 정규식 문자열에 일반 공백을 사용할 수 없다는 것입니다(항상 사용).
\s
,\s+
,\s{1,x}
,\t
,\n
(() => {
const createRegExp = (str, opts) =>
new RegExp(str.raw[0].replace(/\s/gm, ""), opts || "");
const yourRE = createRegExp`
^(([^<>()[\]\\.,;:\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,}))$`;
console.log(yourRE);
const anotherLongRE = createRegExp`
(\byyyy\b)|(\bm\b)|(\bd\b)|(\bh\b)|(\bmi\b)|(\bs\b)|(\bms\b)|
(\bwd\b)|(\bmm\b)|(\bdd\b)|(\bhh\b)|(\bMI\b)|(\bS\b)|(\bMS\b)|
(\bM\b)|(\bMM\b)|(\bdow\b)|(\bDOW\b)
${"gi"}`;
console.log(anotherLongRE);
})();
에서 문자열 new RegExp
백슬래시를 모두 피해야 하기 때문에 어색합니다.더 작은 정규식을 작성하고 연결할 수 있습니다.
이 정규식을 나누자.
/^foo(.*)\bar$/
우리는 나중에 사물을 더 아름답게 만드는 기능을 사용할 것입니다.
function multilineRegExp(regs, options) {
return new RegExp(regs.map(
function(reg){ return reg.source; }
).join(''), options);
}
그리고 이제 락하자꾸나
var r = multilineRegExp([
/^foo/, // we can add comments too
/(.*)/,
/\bar$/
]);
비용이 들기 때문에 한 번만 진짜 정규식을 만들고 그것을 사용해 보세요.
템플릿 리터럴의 놀라운 세계 덕분에 이제 ES6에서 크고, 다중 줄이며, 주석이 잘 달린, 의미론적으로 중첩된 정규식을 작성할 수 있습니다.
//build regexes without worrying about
// - double-backslashing
// - adding whitespace for readability
// - adding in comments
let clean = (piece) => (piece
.replace(/((^|\n)(?:[^\/\\]|\/[^*\/]|\\.)*?)\s*\/\*(?:[^*]|\*[^\/])*(\*\/|)/g, '$1')
.replace(/((^|\n)(?:[^\/\\]|\/[^\/]|\\.)*?)\s*\/\/[^\n]*/g, '$1')
.replace(/\n\s*/g, '')
);
window.regex = ({raw}, ...interpolations) => (
new RegExp(interpolations.reduce(
(regex, insert, index) => (regex + insert + clean(raw[index + 1])),
clean(raw[0])
))
);
이를 사용하여 다음과 같은 정규식을 작성할 수 있습니다.
let re = regex`I'm a special regex{3} //with a comment!`;
출력
/I'm a special regex{3}/
'123hello'
.match(regex`
//so this is a regex
//here I am matching some numbers
(\d+)
//Oh! See how I didn't need to double backslash that \d?
([a-z]{1,3}) /*note to self, this is group #2*/
`)
[2]
력hel
끔깔!!
" 내가 실제로 새로운 줄을 ?", "만약내실가새검한다면야색해라?", "음, 다사용다니합음그런제로인?"를 사용하세요\n
바보야!
파이어폭스와 크롬으로 작업 중입니다.
좋아요, "좀 더 복잡한 건 어때요?"
예, 여기 제가 작업하던 JS 파서를 파괴하는 물체의 일부가 있습니다.
regex`^\s*
(
//closing the object
(\})|
//starting from open or comma you can...
(?:[,{]\s*)(?:
//have a rest operator
(\.\.\.)
|
//have a property key
(
//a non-negative integer
\b\d+\b
|
//any unencapsulated string of the following
\b[A-Za-z$_][\w$]*\b
|
//a quoted string
//this is #5!
("|')(?:
//that contains any non-escape, non-quote character
(?!\5|\\).
|
//or any escape sequence
(?:\\.)
//finished by the quote
)*\5
)
//after a property key, we can go inside
\s*(:|)
|
\s*(?={)
)
)
((?:
//after closing we expect either
// - the parent's comma/close,
// - or the end of the string
\s*(?:[,}\]=]|$)
|
//after the rest operator we expect the close
\s*\}
|
//after diving into a key we expect that object to open
\s*[{[:]
|
//otherwise we saw only a key, we now expect a comma or close
\s*[,}{]
).*)
$`
을 합니다./^\s*((\})|(?:[,{]\s*)(?:(\.\.\.)|(\b\d+\b|\b[A-Za-z$_][\w$]*\b|("|')(?:(?!\5|\\).|(?:\\.))*\5)\s*(:|)|\s*(?={)))((?:\s*(?:[,}\]=]|$)|\s*\}|\s*[{[:]|\s*[,}{]).*)$/
그리고 작은 데모로 그것을 실행하는 것입니까?
let input = '{why, hello, there, "you huge \\"", 17, {big,smelly}}';
for (
let parsed;
parsed = input.match(r);
input = parsed[parsed.length - 1]
) console.log(parsed[1]);
성공적으로 출력
{why
, hello
, there
, "you huge \""
, 17
,
{big
,smelly
}
}
따옴표로 묶은 문자열이 성공적으로 캡처되었습니다.
크롬과 파이어폭스에서 테스트해봤는데, 아주 잘 작동합니다!
궁금하다면 제가 무엇을 하고 있었는지, 그리고 그것의 시연을 확인할 수 있습니다.
파이어폭스는 역참조나 명명된 그룹을 지원하지 않기 때문에 Chrome에서만 작동합니다.따라서 이 답변에 제시된 예는 실제로 중성화된 버전이므로 잘못된 문자열을 쉽게 받아들이도록 속을 수 있습니다.
여기에 좋은 답이 있지만, 완성도를 위해서는 자바스크립트의 핵심 기능인 프로토타입 체인 상속을 언급해야 합니다.다음과 같은 것이 아이디어를 설명합니다.
RegExp.prototype.append = function(re) {
return new RegExp(this.source + re.source, this.flags);
};
let regex = /[a-z]/g
.append(/[A-Z]/)
.append(/[0-9]/);
console.log(regex); //=> /[a-z][A-Z][0-9]/g
위 정규식에 제대로 작동하지 않는 검은색 슬래시가 있습니다.그래서 정규식을 편집했습니다.이메일 유효성 확인을 위해 99.99% 작동하는 정규식을 고려하십시오.
let EMAIL_REGEXP =
new RegExp (['^(([^<>()[\\]\\\.,;:\\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,}))$'].join(''));
과 같이 하십시오.join
다음 구문도 사용할 수 있습니다.
var pattern = new RegExp('^(([^<>()[\]\\.,;:\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,}))$');
단순히 문자열 연산을 사용할 수 있습니다.
var pattenString = "^(([^<>()[\]\\.,;:\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,}))$";
var patten = new RegExp(pattenString);
저는 모든 것을 캡슐화하고 캡처 그룹과 문자 집합을 분할하는 지원을 구현함으로써 코룬의 답변을 개선하려고 노력했습니다. - 이 방법을 훨씬 더 다양하게 만들었습니다.
이 를 이스펫을사면변함수합호니다야출해라고 .combineRegex
결합해야 하는 정규 표현식 개체의 인수입니다.그 구현은 맨 아래에 있습니다.
캡처 그룹은 괄호 하나만 있으면 일부 부분이 남기 때문에 직접 분할할 수 없습니다.브라우저가 예외로 실패할 수 있습니다.
대신 캡처 그룹의 내용을 배열 안에 전달하는 것입니다.다음과 같은 경우 괄호가 자동으로 추가됩니다.combineRegex
배열을 발견합니다.
또한 계량기는 무언가를 따라야 합니다.어떤 이유로 정규식을 정량자 앞에서 분할해야 하는 경우 괄호 한 쌍을 추가해야 합니다.이러한 파일은 자동으로 제거됩니다.요점은 빈 캡처 그룹은 매우 쓸모가 없으며 이러한 방식으로 정량화자는 참조해야 할 것이 있습니다.비캡처 그룹과 같은 경우에도 동일한 방법을 사용할 수 있습니다(/(?:abc)/
되다[/()?:abc/]
).
이는 간단한 예를 사용하여 가장 잘 설명할 수 있습니다.
var regex = /abcd(efghi)+jkl/;
다음이 될 것입니다.
var regex = combineRegex(
/ab/,
/cd/,
[
/ef/,
/ghi/
],
/()+jkl/ // Note the added '()' in front of '+'
);
문자집합분하야경다용객수있사습니할체를우는할을해▁if{"":[regex1, regex2, ...]}
(어레대신이▁( ()[regex1, regex2, ...]
되어 있으면 이든 될 수 키의 내용은 개체에 키가 하나만 포함되어 있으면 됩니다.대신에 참고하십시오.()
은 야합니다해사를 사용해야 .]
첫 번째 문자를 정량자로 해석할 수 있는지 여부를 더미로 시작합니다.예./[+?]/
되다{"":[/]+?/]}
다음은 스니펫과 더 완전한 예입니다.
function combineRegexStr(dummy, ...regex)
{
return regex.map(r => {
if(Array.isArray(r))
return "("+combineRegexStr(dummy, ...r).replace(dummy, "")+")";
else if(Object.getPrototypeOf(r) === Object.getPrototypeOf({}))
return "["+combineRegexStr(/^\]/, ...(Object.entries(r)[0][1]))+"]";
else
return r.source.replace(dummy, "");
}).join("");
}
function combineRegex(...regex)
{
return new RegExp(combineRegexStr(/^\(\)/, ...regex));
}
//Usage:
//Original:
console.log(/abcd(?:ef[+A-Z0-9]gh)+$/.source);
//Same as:
console.log(
combineRegex(
/ab/,
/cd/,
[
/()?:ef/,
{"": [/]+A-Z/, /0-9/]},
/gh/
],
/()+$/
).source
);
개인적으로, 저는 덜 복잡한 정규식을 원합니다.
/\S+@\S+\.\S+/
네, 현재 패턴보다 정확도가 떨어지지만, 무엇을 달성하기 위해 노력하고 있습니까?사용자가 입력할 수 있는 우발적인 오류를 탐지하려고 노력하고 있습니까? 아니면 사용자가 잘못된 주소를 입력하려고 시도할까 봐 걱정하십니까?첫 번째라면 좀 더 쉬운 패턴을 택하겠어요.후자의 경우 해당 주소로 전송된 전자 메일에 응답하여 확인하는 것이 더 나은 옵션일 수 있습니다.
그러나 현재 패턴을 사용하려는 경우 다음과 같은 더 작은 하위 패턴으로 패턴을 작성하면 (IMO) 읽기가 더 쉬워지고 유지보수할 수 있습니다.
var box1 = "([^<>()[\]\\\\.,;:\s@\"]+(\\.[^<>()[\\]\\\\.,;:\s@\"]+)*)";
var box2 = "(\".+\")";
var host1 = "(\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])";
var host2 = "(([a-zA-Z\-0-9]+\\.)+[a-zA-Z]{2,})";
var regex = new RegExp("^(" + box1 + "|" + box2 + ")@(" + host1 + "|" + host2 + ")$");
@해시브라운의 훌륭한 답변이 저를 올바른 방향으로 이끌었습니다.여기 이 블로그에서 영감을 받은 제 버전이 있습니다.
function regexp(...args) {
function cleanup(string) {
// remove whitespace, single and multi-line comments
return string.replace(/\s+|\/\/.*|\/\*[\s\S]*?\*\//g, '');
}
function escape(string) {
// escape regular expression
return string.replace(/[-.*+?^${}()|[\]\\]/g, '\\$&');
}
function create(flags, strings, ...values) {
let pattern = '';
for (let i = 0; i < values.length; ++i) {
pattern += cleanup(strings.raw[i]); // strings are cleaned up
pattern += escape(values[i]); // values are escaped
}
pattern += cleanup(strings.raw[values.length]);
return RegExp(pattern, flags);
}
if (Array.isArray(args[0])) {
// used as a template tag (no flags)
return create('', ...args);
}
// used as a function (with flags)
return create.bind(void 0, args[0]);
}
다음과 같이 사용합니다.
regexp('i')`
//so this is a regex
//here I am matching some numbers
(\d+)
//Oh! See how I didn't need to double backslash that \d?
([a-z]{1,3}) /*note to self, this is group #2*/
`
작성을 RegExp
객체:
/(\d+)([a-z]{1,3})/i
언급URL : https://stackoverflow.com/questions/12317049/how-to-split-a-long-regular-expression-into-multiple-lines-in-javascript
'programing' 카테고리의 다른 글
Spring Data JDBC: 리포지토리에서 세 번째 수준부터 중첩된 엔티티를 저장하지 않습니다. (0) | 2023.08.25 |
---|---|
두 개의 다른 서버에서 테이블 조인 (0) | 2023.08.25 |
장고의 컬렉션 스태틱은 무슨 의미가 있습니까? (0) | 2023.08.20 |
[NSDate date]에서 현재 날짜를 가져오지만 시간을 오전 10시로 설정합니다. (0) | 2023.08.20 |
husky > 사전 커밋 후크 실패(바이패스하려면 --no-commit hook 추가) (0) | 2023.08.20 |