사용자로부터 정규표현식과 문자열을 입력받아 문자열이 정규표현식과 일치 한지 검증하는 코드를 작성하시오(단, 정규표현식은 아래의 형태를 가지는 공백이 없는 문자열로 입력받는다. 또, Pattern과 Macher클래스는 사용 할 수 없다.)
^x x로 시작하는 문자열로 ^는 시작을 의미한다.
x$ x로 끝나는 문자열로 $는 끝을 의미한다.
.x 임의의 한 문자와 x가 결합된 형태로 .은 임의의 한 문자를 의미한다.
x+ x가 1번이상 반복됨을 의미한다.
x* x가 0번이상 반복됨을 의미한다.
x|y x나 y둘 중 하나가 표시 될 수 있음을 의미하고 |는 또는을 의미한다.
x{n} x가 n번 반복됨을 의미한다.
x{n,} x가 n번 이상 반복됨을 의미한다.
x{n,m} x가 >n번 이상 m번 이하 반복됨을 의미한다.
(xyz) xyz라는 문자열을 하나의 그룹으로 사용함을 의미한다.
[x-z] x ~ z사이의 문자 하나를 의미한다.
예)^a[b-y]*z$
"abcd" -> false
"az" -> true
"abcz" -> true
"bcdz" -> false
3개의 풀이가 있습니다.
파이썬 3.6
data_list = ['abcd','az','abcz','bcdz']
def standard(n,data):
alphabet = 'abcdefghijklmnopqrstuvwxyz'
t = 0
# [x-z] 표현 검증
# 다른 표현식과 연속되어 사용되는 경우 표현식 기호가 문자로 인식될 수 있는 경우가 있으므로, 해당 문자가 data에서 몇 번 인덱스(t)인지도 함께 검증
if '[' in n and '-' in n and ']' in n:
if '^' in n:
t +=1
if '.' in n[:n.index('[')]:
if n.index('.') == n.index('[')-1:
t += 1
else:
t += 2
if '+' in n[:n.index('[')]:
t += data.count(n[n.index('+')-1])
if '*' in n[:n.index('[')]:
t += data.count(n[n.index('+')-1])
if '{' in n[:n.index('[')] and '}' in n[:n.index('[')]:
t += int(n[(n.index('{')+1):n.index('}')])
if '{' in n[:n.index('[')] and ',}' in n[:n.index('[')]:
t += int(n[(n.index('{')+1):n.index(',')])
if '{' in n[:n.index('[')] and ',' in n[:n.index('[')] and '}' in n[:n.index('[')]:
t += data.count(n[n.index('{')-1])
if '(' in n[:n.index('[')] and ')' in n[:n.index('[')]:
t += len(n[(n.index('(')+1):n.index(')')])
if n[n.index(']')+1] == '*' and data[t] not in alphabet[alphabet.index(n[n.index('-')-1]):alphabet.index(n[n.index('-')+1])+1]:
pass
elif data[t] in alphabet[alphabet.index(n[n.index('-')-1]):alphabet.index(n[n.index('-')+1])+1]:
pass
else:
return "false"
# ^x 표현 검증
if '^' in n:
if n[n.index('^')+1] == data[0]:
pass
else:
return "false"
# x$ 표현 검증
if '$' in n:
if n[n.index('$')-1] == data[len(data)-1]:
pass
else:
return "false"
# .x 표현 검증
if '.' in n:
if n[n.index('.')+1] in data and len(data) > 1:
pass
else:
return "false"
# x+ 표현 검증
if '+' in n:
if data.count(n[n.index('+')-1]) >= 1:
pass
else:
return "false"
# x* 표현 검증
if '*' in n:
if n[n.index('*')-1] == ']':
if data.count(data[t]) >= 0:
pass
else:
return "false"
else:
if data.count(n[n.index('*')-1]) >= 0:
pass
else:
return "false"
# x|y 표현 검증
if '|' in n:
if (n[n.index('|')-1] in data and n[n.index('|')+1] not in data) or (n[n.index('|')-1] not in data and n[n.index('|')+1] in data):
pass
else:
return "false"
# x{n} 표현 검증
if '{' in n and '}' in n:
if n[n.index('{')-1]*int(n[(n.index('{')+1):n.index('}')]) in data:
pass
else:
return "false"
# x{n,} 표현 검증
if '{' in n and ',}' in n:
if data.count(n[n.index('{')-1]) >= int(n[(n.index('{')+1):n.index(',')]) :
pass
else:
return "false"
# x{n,m} 표현 검증
if '{' in n and ',' in n and '}' in n:
if int(n[(n.index('{')+1):n.index(',')]) <= n[n.index('{')-1] <= int(n[(n.index(',')+1):n.index('}')]):
pass
else:
return "false"
# (xyz) 표현 검증
if '(' in n and ')' in n:
if n[(n.index('(')+1):n.index(')')] in data:
pass
else:
return "false"
return "true"
if __name__ == "__main__":
# n = input("정규표현식을 입력하세요:")
n = '^a[b-y]*z$'
print(n,'\n')
for data in data_list:
print('"%s" ->'%data,standard(n,data))
^a[b-y]*z$
"abcd" -> false
"az" -> true
"abcz" -> true
"bcdz" -> false
import re
def regular(a, b):
p = re.compile(a)
if p.match(b):
return True
else:
return False
a = input("정규표현식을 입력하시오 : ")
while 1:
b = input("문자열을 입력하시오 : ")
if b == '':
break
else:
print(regular(a, b))
def isCorrectString(inpStr, regStr):
res = 'true'
iL, iR = 0, len(inpStr)-1
rL, rR = 1, len(regStr)-2
if inpStr[iL] != regStr[rL] or inpStr[iR] != regStr[rR]:
print('{0} -> {1}'.format(inpStr, 'false'))
return
iL, iR, rL, rR = iL + 1, iR - 1, rL + 1, rR - 1
while iL <= iR and rL <= rR:
if inpStr[iL] == regStr[rL] and inpStr[iR] == regStr[rR]:
iL, iR, rL, rR = iL+1, iR-1, rL+1, rR-1
elif regStr[rL] == '.' or inpStr[iL] == regStr[rL]:
iL, rL = iL + 1, rL + 1
elif regStr[rL+1] == '|' and regStr[rL + 2] == inpStr[iL]:
iL, rL = iL + 1, rL + 1
elif regStr[rL] == '+' or regStr[rL] == '*':
rL += 1
while iL <= iR and inpStr[iL-1] == inpStr[iL]:
iL += 1
elif regStr[rL] == '[' and regStr[rL+2] == '-' and regStr[rL+4] == ']':
if regStr[rL + 5] == '*':
while iL <= iR and regStr[rL+1] <= inpStr[iL] <= regStr[rL + 3]:
iL += 1
rL += 6
elif regStr[rL + 5] == '+':
if not (regStr[rL+1] <= inpStr[iL] <= regStr[rL + 2]):
res = 'false'
break
while regStr[rL+1] <= inpStr[iL] <= regStr[rL + 2]:
iL += 1
rL += 5
else:
if not (regStr[rL+1] <= inpStr[iL] <= regStr[rL + 2]):
res = 'false'
break
iL, rL = iL + 1, rL + 4
elif regStr[rL] == ']':
rL += 1
elif regStr[rL+1] == '*':
rL += 2
elif regStr[rL] == '{' and regStr[rL + 2] == ',':
if regStr[rL + 3] == '}':
cnt = 1
while inpStr[iL-1] == inpStr[iL]:
iL += 1
cnt += 1
if cnt < int(inpStr[rL+1]):
res = 'false'
break
rL += 4
elif regStr[rL + 4] == '}':
cnt = 1
while inpStr[iL - 1] == inpStr[iL]:
iL += 1
cnt += 1
if cnt < int(inpStr[rL + 1]) or cnt > int(inpStr[rL+3]):
res = 'false'
break
rL += 5
else:
res = 'false'
break
if res == 'false':
print('{0} -> {1}'.format(inpStr, 'false'))
else:
print('{0} -> {1}'.format(inpStr, 'true'))
# inString = input('문자열: ')
# regularEx = input('정규표현식: ')
# isCorrectString(inString, regularEx)
strings = ['abcd','az','abcz','bcdz']
for st in strings:
isCorrectString(st, '^a[b-y]*z$')