📑정규 표현식이란?
특정한 규칙을 가진 문자열의 집합을 표현하기 위해 쓰이는 형식입니다.
줄여서 "정규식"이라고도 합니다.
정규표현식을 사용하여 비밀번호 영문과 특수문자조합, 이메일형식, 주민등록번호 형식, 핸드폰번호 형식 등
제대로 입력했는지 검증을 할 수 있습니다.
📝정규표현식 문법
^ : 문자열의 시작
$ : 문자열의 끝
. : 줄 바꿈 제외 문자 한 개를 의미. '.'이 위치한 곳에 어떤 문자든지 1개의 문자가 들어감.
[ ] : [ ] 사이에 있는 문자 중 한 개를 의미. (Ex. [abc]는 a, b, c 중 하나)
[^] : not의 의미로, 대괄호에서 쓴다면 [^abc] : a, b, c 제외하고 나머지를 의미.
| : or을 의미. a|b : a 또는 b.
() : ( ) 안의 문자를 하나로 인식, 서브 패턴을 지정할 때 사용. abc|abd -> ab(c|d)로 바꿀 수 있음.
re? : 앞의 문자가 0회 또는 1회 이상 등장. a? b는 a가 나올 수도, 없을 수도 있음. ab, b.
re* : 앞의 문자가 0회 이상 등장. a*b : b, ab, aaab, aaab..
re+ : 앞의 문자가 1회 이상 등장. a+b : ab, aab, aaab..
re{n} : 앞의 문자가 n개 나옴. a {2} b : aab
re{n,} : 앞의 문자가 n개 이상 나옴. a {2,} b : aab, aaab, aaaab..
re{n, m} : 앞의 문자가 n개 이상 m개 이하로 나옴. a {1,3 } b : ab, aab, aaab
\s : 공백 제거
\t : 탭
\d : 숫자, [0-9]와 동일
\b : 단어의 경계, 문자 사이의 공백
\w : 알파벳이나 숫자, [a-zA-Z0-9_]와 동일
\W : 비단어 문자와 일치
📚정규 표현식 예시
숫자만 : ^[0-9]*$
영문자만: ^[a-zA-Z]*$
한글만 : ^[가-힣]*$
영어 & 숫자만 : ^[a-zA-Z0-9]*$
Email : ^[a-zA-Z0-9]+@[a-zA-Z0-9]+$
Phone : ^01(?:0|1|[6-9]) - (?:\d{3}|\d{4}) - \d{4}$
주민등록번호 : \d{6} \- [1-4]\d{6}
//이메일 유효성
Pattern.matches("[0-9a-zA-Z]+(.[_a-z0-9-]+)*@(?:\\w+\\.)+\\w+$", EmailAddr)
//핸드폰번호 유효성
Pattern.matches("^01(?:0|1|[6-9]) - (?:\\d{3}|\\d{4}) - \\d{4}$", Phone_num)
//비밀번호 여러가지 조건으로 유효성 검사
val pwPattern1 = "^(?=.*[A-Za-z])(?=.*[0-9])[A-Za-z[0-9]]{8,20}$" // 영문, 숫자
val pwPattern2 = "^(?=.*[0-9])(?=.*[$@$!%*#?&.])[[0-9]$@$!%*#?&.]{8,20}$" // 숫자, 특수문자
val pwPattern3 = "^(?=.*[A-Za-z])(?=.*[$@$!%*#?&.])[A-Za-z$@$!%*#?&.]{8,20}$" // 영문, 특수문자
val pwPattern4 = "^(?=.*[A-Za-z])(?=.*[0-9])(?=.*[$@$!%*#?&.])[A-Za-z[0-9]$@$!%*#?&.]{8,20}$" // 영문, 숫자, 특수문자
Pattern.matches(pwPattern1, PW)
//주민번호 유효성
Pattern.matches("^\\d{6}[1-4]\\d{6}", ssnum)
//아이피 주소 유효성
Pattern.matches("([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})", IPAddr)
🔍정규표현식을 이용한 회원가입 예제
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.RegisterExample"
tools:targetApi="31">
<activity
android:name=".RegisterActivity"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:exported="false"/>
</application>
</manifest>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="로그인 성공!"
android:textSize="50sp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
activity_register.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".RegisterActivity">
<TextView
android:id="@+id/tv_registerText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="회원가입"
android:textSize="50sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- 1층 -->
<TextView
android:id="@+id/tv_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="이메일"
android:textSize="30sp"
android:layout_marginTop="10dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_registerText" />
<EditText
android:id="@+id/et_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="이메일을 입력해주세요."
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_email" />
<!-- 2층 -->
<TextView
android:id="@+id/tv_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="비밀번호"
android:textSize="30sp"
android:layout_marginTop="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/et_email" />
<EditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="비밀번호를 입력해 주세요."
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_password" />
<!-- 3층 -->
<TextView
android:id="@+id/textView3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="비밀번호 확인"
android:textSize="30sp"
android:layout_marginTop="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/et_password" />
<EditText
android:id="@+id/et_passwordCheck"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="비밀번호를 한번 더 입력해 주세요."
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView3" />
<!-- 버튼 -->
<Button
android:id="@+id/btn_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="회원가입"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/et_passwordCheck" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.kt
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
RegisterActivity.kt
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import java.util.regex.Pattern
class RegisterActivity : AppCompatActivity() {
private val etEmail: EditText by lazy { findViewById(R.id.et_email) }
private val etPassword: EditText by lazy { findViewById(R.id.et_password) }
private val etPasswordCheck: EditText by lazy { findViewById(R.id.et_passwordCheck) }
private val btnButton: Button by lazy { findViewById(R.id.btn_button) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_register)
btnButton.setOnClickListener {
val email = etEmail.text.toString()
val password = etPassword.text.toString()
val passwordCheck = etPasswordCheck.text.toString()
val passwordRegex =
"^(?=.*[A-Za-z])(?=.*[0-9])(?=.*[$@$!%*#?&.])[A-Za-z[0-9]$@$!%*#?&.]{8,16}$"
val emailRegex = "[0-9a-zA-Z]+(.[_a-z0-9-]+)*@(?:\\w+\\.)+\\w+$"
val passwordPattern = Pattern.matches(passwordRegex, password)
val emailPattern = Pattern.matches(emailRegex, email)
when {
listOf(email, password, passwordCheck).any { it.isBlank() } ->
Toast.makeText(this, "입력하지 않은 란이 존재합니다.", Toast.LENGTH_SHORT).show()
!emailPattern -> Toast.makeText(this, "이메일 형식이 아닙니다.", Toast.LENGTH_SHORT).show()
!passwordPattern -> Toast.makeText(
this,
"비밀번호는 영문 + 특수문자 + 숫자 8자이상 16자이하로 조합해주세요.",
Toast.LENGTH_SHORT
).show()
password != passwordCheck -> Toast.makeText(
this,
"비밀번호가 일치하지 않습니다.",
Toast.LENGTH_SHORT
).show()
else -> {
Toast.makeText(this, "회원가입이 완료되었습니다.", Toast.LENGTH_SHORT).show()
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
finish()
}
}
}
}
}
'Android Studio > - Programming' 카테고리의 다른 글
[안드로이드/viewBinding] 뷰바인딩은 무엇이고 어떻게 사용할까? (0) | 2024.04.30 |
---|---|
[안드로이드] 액티비티 생명주기 ( Activity Lifecycle ) (0) | 2024.04.24 |
[코틀린] lateinit과 by lazy의 차이점 (0) | 2024.03.29 |
[코틀린/OOP] OOP (객체지향 프로그래밍) 란 무엇인가? (0) | 2024.03.25 |
[코틀린] Abstract class와 Interface 차이점 (0) | 2024.03.19 |
주코딩의 개발 노트!
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!